Skip to main content

sp1_prover/worker/
error.rs

1use anyhow::anyhow;
2use slop_futures::pipeline::SubmitError;
3use sp1_core_executor::ExecutionError;
4use sp1_core_machine::utils::SP1CoreProverError;
5use tonic::Code;
6
7#[derive(Debug)]
8pub enum TaskError {
9    Retryable(anyhow::Error),
10    Fatal(anyhow::Error),
11    Execution(ExecutionError),
12}
13
14impl From<anyhow::Error> for TaskError {
15    fn from(err: anyhow::Error) -> Self {
16        if err.is::<reqwest::Error>() {
17            Self::Retryable(err)
18        } else if err.is::<tonic::Status>() {
19            err.downcast::<tonic::Status>().unwrap().into()
20        } else {
21            Self::Fatal(err)
22        }
23    }
24}
25
26impl From<tonic::Status> for TaskError {
27    fn from(err: tonic::Status) -> Self {
28        match err.code() {
29            Code::Internal
30            | Code::Unavailable
31            | Code::Unknown
32            | Code::Cancelled
33            | Code::DeadlineExceeded
34            | Code::ResourceExhausted
35            | Code::Aborted
36            | Code::DataLoss => Self::Retryable(err.into()),
37            _ => Self::Fatal(err.into()),
38        }
39    }
40}
41
42impl From<SP1CoreProverError> for TaskError {
43    fn from(err: SP1CoreProverError) -> Self {
44        Self::Fatal(err.into())
45    }
46}
47
48impl From<ExecutionError> for TaskError {
49    fn from(err: ExecutionError) -> Self {
50        Self::Execution(err)
51    }
52}
53
54impl From<eyre::Report> for TaskError {
55    fn from(err: eyre::Report) -> Self {
56        Self::Fatal(anyhow!(Box::new(err)))
57    }
58}
59
60impl From<SubmitError> for TaskError {
61    fn from(err: SubmitError) -> Self {
62        Self::Fatal(anyhow!(err))
63    }
64}
65
66impl std::error::Error for TaskError {
67    fn description(&self) -> &str {
68        match self {
69            TaskError::Retryable(_) => "Retryable",
70            TaskError::Fatal(_) => "Fatal",
71            TaskError::Execution(_) => "Execution",
72        }
73    }
74}
75
76impl std::fmt::Display for TaskError {
77    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
78        match self {
79            TaskError::Retryable(err) => write!(f, "Retryable: {}", err),
80            TaskError::Fatal(err) => write!(f, "Fatal: {}", err),
81            TaskError::Execution(err) => write!(f, "Execution: {}", err),
82        }
83    }
84}