1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use ntex_bytes::Bytes;
use ntex_h2::{OperationError, StreamError};
use ntex_http::{error::Error as HttpError, HeaderMap, StatusCode};

use crate::encoding::DecodeError;
use crate::status::GrpcStatus;

#[derive(thiserror::Error, Debug)]
pub enum ServiceError {
    #[error("Canceled")]
    Canceled,
    #[error("Http error {0:?}")]
    Http(Option<HttpError>),
    #[error("{0}")]
    Decode(#[from] DecodeError),
    #[error("Http operation error: {0}")]
    Operation(#[from] OperationError),
    #[error("Http stream error: {0}")]
    Stream(#[from] StreamError),
    #[error("Http response {0:?}, headers: {1:?}, body: {2:?}")]
    Response(Option<StatusCode>, HeaderMap, Bytes),
    #[error("Got eof without payload with {0:?}, headers: {1:?}")]
    UnexpectedEof(Option<StatusCode>, HeaderMap),
    #[error("Grpc status {0:?}, headers: {1:?}")]
    GrpcStatus(GrpcStatus, HeaderMap),
}

impl From<HttpError> for ServiceError {
    fn from(err: HttpError) -> Self {
        Self::Http(Some(err))
    }
}

impl Clone for ServiceError {
    fn clone(&self) -> Self {
        match self {
            ServiceError::Canceled => ServiceError::Canceled,
            ServiceError::Http(_) => ServiceError::Http(None),
            ServiceError::Decode(err) => ServiceError::Decode(err.clone()),
            ServiceError::Operation(err) => ServiceError::Operation(err.clone()),
            ServiceError::Stream(err) => ServiceError::Stream(*err),
            ServiceError::Response(st, hdrs, payload) => {
                ServiceError::Response(*st, hdrs.clone(), payload.clone())
            }
            ServiceError::UnexpectedEof(st, hdrs) => {
                ServiceError::UnexpectedEof(*st, hdrs.clone())
            }
            ServiceError::GrpcStatus(st, hdrs) => ServiceError::GrpcStatus(*st, hdrs.clone()),
        }
    }
}