viaduct/
error.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5pub type Result<T, E = ViaductError> = std::result::Result<T, E>;
6
7#[derive(Debug, thiserror::Error, uniffi::Error)]
8pub enum ViaductError {
9    #[error("[no-sentry] Illegal characters in request header '{0}'")]
10    RequestHeaderError(String),
11
12    #[error("[no-sentry] Backend error: {0}")]
13    BackendError(String),
14
15    #[error("[no-sentry] Network error: {0}")]
16    NetworkError(String),
17
18    #[error("The rust-components network backend only be initialized once!")]
19    BackendAlreadyInitialized,
20
21    #[error("The rust-components network backend must be initialized before use!")]
22    BackendNotInitialized,
23
24    #[error("Backend already initialized.")]
25    SetBackendError,
26
27    /// Note: we return this if the server returns a bad URL with
28    /// its response. This *probably* should never happen, but who knows.
29    #[error("[no-sentry] URL Parse Error: {0}")]
30    UrlError(String),
31
32    #[error("[no-sentry] Validation error: URL does not use TLS protocol.")]
33    NonTlsUrl,
34}
35
36impl ViaductError {
37    pub fn new_backend_error(msg: impl Into<String>) -> Self {
38        Self::BackendError(msg.into())
39    }
40}
41
42impl From<url::ParseError> for ViaductError {
43    fn from(e: url::ParseError) -> Self {
44        ViaductError::UrlError(e.to_string())
45    }
46}
47
48/// This error is returned as the `Err` result from
49/// [`Response::require_success`].
50///
51/// Note that it's not a variant on `Error` to distinguish between errors
52/// caused by the network, and errors returned from the server.
53#[derive(thiserror::Error, Debug, Clone)]
54#[error("Error: {method} {url} returned {status}")]
55pub struct UnexpectedStatus {
56    pub status: u16,
57    pub method: crate::Method,
58    pub url: url::Url,
59}
60
61/// Map errors from external crates like `tokio` and `hyper` to `Error::BackendError`
62///
63/// This works for any error that implements ToString
64pub trait MapBackendError {
65    type Ok;
66
67    fn map_backend_error(self) -> Result<Self::Ok>;
68}
69
70impl<T, E: ToString> MapBackendError for std::result::Result<T, E> {
71    type Ok = T;
72
73    fn map_backend_error(self) -> Result<T> {
74        self.map_err(|e| ViaductError::BackendError(e.to_string()))
75    }
76}
77
78/// Implement From<UnexpectedUniFFICallbackError> so that unexpected errors when invoking backend
79/// callback interface methods get converted to `BackendError`.
80impl From<uniffi::UnexpectedUniFFICallbackError> for ViaductError {
81    fn from(error: uniffi::UnexpectedUniFFICallbackError) -> Self {
82        ViaductError::BackendError(error.to_string())
83    }
84}