Skip to main content

redevplugin_worker_sdk/
error.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::fmt;
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
7pub enum ErrorCode {
8    InvalidArgument,
9    PermissionDenied,
10    NotFound,
11    AlreadyExists,
12    ResourceClosed,
13    Canceled,
14    Timeout,
15    WouldBlock,
16    IoError,
17    NetworkError,
18    ResourceLimit,
19    Internal,
20    RuntimeUnavailable,
21    RedirectRequiresReplay,
22    #[serde(other)]
23    Unknown,
24}
25
26#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
27pub struct Error {
28    pub code: ErrorCode,
29    pub message: String,
30    #[serde(default)]
31    pub retryable: bool,
32    #[serde(default)]
33    pub details: Value,
34}
35
36impl Error {
37    pub(crate) fn internal(message: impl Into<String>) -> Self {
38        Self {
39            code: ErrorCode::Internal,
40            message: message.into(),
41            retryable: false,
42            details: Value::Null,
43        }
44    }
45
46    pub(crate) fn from_abi_status(status: i32) -> Self {
47        let code = match status {
48            -1 => ErrorCode::InvalidArgument,
49            -2 => ErrorCode::PermissionDenied,
50            -3 => ErrorCode::NotFound,
51            -4 => ErrorCode::AlreadyExists,
52            -5 => ErrorCode::ResourceClosed,
53            -6 => ErrorCode::Canceled,
54            -7 => ErrorCode::Timeout,
55            -8 => ErrorCode::WouldBlock,
56            -9 => ErrorCode::IoError,
57            -10 => ErrorCode::NetworkError,
58            -11 => ErrorCode::ResourceLimit,
59            -12 => ErrorCode::Internal,
60            -13 => ErrorCode::RuntimeUnavailable,
61            -14 => ErrorCode::RedirectRequiresReplay,
62            _ => ErrorCode::Unknown,
63        };
64        Self {
65            code,
66            message: format!("Worker API hostcall failed with ABI status {status}"),
67            retryable: false,
68            details: Value::Null,
69        }
70    }
71}
72
73impl fmt::Display for Error {
74    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
75        write!(formatter, "{:?}: {}", self.code, self.message)
76    }
77}
78
79impl std::error::Error for Error {}
80
81pub type Result<T> = std::result::Result<T, Error>;