REST backend: abort at permanent errors

This commit is contained in:
Alexander Weiss 2022-09-26 23:21:08 +02:00
parent 13caa4291b
commit a2fb42d242

View File

@ -2,14 +2,33 @@ use std::time::Duration;
use anyhow::{bail, Result};
use async_trait::async_trait;
use backoff::{backoff::Backoff, ExponentialBackoff, ExponentialBackoffBuilder};
use backoff::{backoff::Backoff, Error, ExponentialBackoff, ExponentialBackoffBuilder};
use bytes::Bytes;
use log::*;
use reqwest::{Client, Url};
use reqwest::{Client, Response, Url};
use serde::Deserialize;
use super::{FileType, Id, ReadBackend, WriteBackend};
// trait CheckError to add user-defined methoed check_error on Response
trait CheckError {
fn check_error(self) -> std::result::Result<Response, Error<reqwest::Error>>;
}
impl CheckError for Response {
// Check reqwest Response for error and treat errors as permanent or transient
fn check_error(self) -> std::result::Result<Response, Error<reqwest::Error>> {
match self.error_for_status() {
Ok(t) => Ok(t),
Err(err) if err.status().unwrap().is_client_error() => Err(Error::Permanent(err)),
Err(err) => Err(Error::Transient {
err,
retry_after: None,
}),
}
}
}
#[derive(Clone)]
struct MaybeBackoff(Option<ExponentialBackoff>);
@ -32,7 +51,6 @@ pub struct RestBackend {
backoff: MaybeBackoff,
}
// TODO for backoff: Handle transient vs permanent errors!
fn notify(err: reqwest::Error, duration: Duration) {
warn!("Error {err} at {duration:?}, retrying");
}
@ -136,7 +154,7 @@ impl ReadBackend for RestBackend {
.header("Accept", "application/vnd.x.restic.rest.v2")
.send()
.await?
.error_for_status()?
.check_error()?
.json::<Vec<ListEntry>>()
.await?;
Ok(list.into_iter().map(|i| (i.name, i.size)).collect())
@ -155,7 +173,7 @@ impl ReadBackend for RestBackend {
.get(self.url(tpe, id))
.send()
.await?
.error_for_status()?
.check_error()?
.bytes()
.await?
.into_iter()
@ -185,7 +203,7 @@ impl ReadBackend for RestBackend {
.header("Range", header_value.clone())
.send()
.await?
.error_for_status()?
.check_error()?
.bytes()
.await?
.into_iter()
@ -207,7 +225,7 @@ impl WriteBackend for RestBackend {
.post(self.url.join("?create=true").unwrap())
.send()
.await?
.error_for_status()?;
.check_error()?;
Ok(())
},
notify,
@ -232,7 +250,7 @@ impl WriteBackend for RestBackend {
.unwrap()
.send()
.await?
.error_for_status()?;
.check_error()?;
Ok(())
},
notify,
@ -249,7 +267,7 @@ impl WriteBackend for RestBackend {
.delete(self.url(tpe, id))
.send()
.await?
.error_for_status()?;
.check_error()?;
Ok(())
},
notify,