redevplugin_worker_sdk/
error.rs1use 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>;