sp1_prover/worker/
error.rs1use 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}