11use crate :: error_code:: {
2- ACCOUNT_PARSE_ERROR_CODE , EMAIL_SERVICE_ERROR_CODE , GAS_ESTIMATION_FAILED_CODE ,
3- INVALID_ADDRESS_FORMAT_CODE , INVALID_AMOUNT_CODE , INVALID_CHAIN_ID_CODE ,
4- INVALID_HEX_FORMAT_CODE , INVALID_USER_OPERATION_CODE , INVALID_WALLET_INDEX_CODE ,
5- SIGNATURE_SERVICE_UNAVAILABLE_CODE , SIGNER_SERVICE_ERROR_CODE , STORAGE_SERVICE_ERROR_CODE ,
6- UNEXPECTED_RESPONSE_TYPE_CODE ,
2+ EMAIL_SERVICE_ERROR_CODE , GAS_ESTIMATION_FAILED_CODE , INVALID_BACKEND_RESPONSE_CODE ,
3+ INVALID_USEROP_CODE , PUMPX_SERVICE_ERROR_CODE , SIGNER_SERVICE_ERROR_CODE ,
4+ STORAGE_SERVICE_ERROR_CODE , WILDMETA_SERVICE_ERROR_CODE ,
75} ;
8- use jsonrpsee:: types:: ErrorObject ;
6+ use jsonrpsee:: types:: { ErrorCode , ErrorObject , ErrorObjectOwned } ;
7+ use parity_scale_codec:: Codec ;
8+ use pumpx:: methods:: common:: ApiResponse ;
99use serde:: { Deserialize , Serialize } ;
1010
1111#[ derive( Debug , Clone , Serialize , Deserialize ) ]
@@ -17,6 +17,8 @@ pub struct DetailedError {
1717
1818#[ derive( Debug , Clone , Serialize , Deserialize ) ]
1919pub struct ErrorDetails {
20+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
21+ pub backend_response : Option < BackendResponse > ,
2022 #[ serde( skip_serializing_if = "Option::is_none" ) ]
2123 pub field : Option < String > ,
2224 #[ serde( skip_serializing_if = "Option::is_none" ) ]
@@ -29,12 +31,19 @@ pub struct ErrorDetails {
2931 pub suggestion : Option < String > ,
3032}
3133
34+ #[ derive( Debug , Clone , Serialize , Deserialize ) ]
35+ pub struct BackendResponse {
36+ pub code : i32 ,
37+ pub message : String ,
38+ }
39+
3240impl DetailedError {
3341 pub fn new ( code : i32 , message : impl Into < String > ) -> Self {
3442 Self {
3543 code,
3644 message : message. into ( ) ,
3745 details : ErrorDetails {
46+ backend_response : None ,
3847 field : None ,
3948 expected : None ,
4049 received : None ,
@@ -69,76 +78,49 @@ impl DetailedError {
6978 self
7079 }
7180
72- pub fn to_error_object ( & self ) -> ErrorObject < ' static > {
81+ pub fn with_backend_response ( mut self , code : i32 , message : impl Into < String > ) -> Self {
82+ self . details . backend_response = Some ( BackendResponse { code, message : message. into ( ) } ) ;
83+ self
84+ }
85+
86+ pub fn to_rpc_error ( & self ) -> ErrorObjectOwned {
7387 ErrorObject :: owned ( self . code , self . message . clone ( ) , Some ( self . details . clone ( ) ) )
7488 }
7589}
7690
7791impl DetailedError {
78- pub fn invalid_chain_id ( chain_id : u64 , supported_chains : & [ u64 ] ) -> Self {
79- Self :: new ( INVALID_CHAIN_ID_CODE , "Invalid or unsupported chain ID" )
80- . with_field ( "chain_id" )
81- . with_received ( chain_id. to_string ( ) )
82- . with_expected ( format ! ( "One of: {:?}" , supported_chains) )
83- . with_suggestion ( "Use a supported chain ID from the list" )
92+ pub fn internal_error ( reason : & str ) -> Self {
93+ Self :: new ( ErrorCode :: InternalError . code ( ) , ErrorCode :: InternalError . message ( ) )
94+ . with_reason ( reason)
8495 }
8596
86- pub fn invalid_wallet_index ( index : u32 , max_index : u32 ) -> Self {
87- Self :: new ( INVALID_WALLET_INDEX_CODE , "Wallet index out of bounds" )
88- . with_field ( "wallet_index" )
89- . with_received ( index. to_string ( ) )
90- . with_expected ( format ! ( "0 to {}" , max_index) )
91- . with_suggestion ( format ! ( "Use a wallet index between 0 and {}" , max_index) )
97+ pub fn parse_error ( reason : & str ) -> Self {
98+ Self :: new ( ErrorCode :: ParseError . code ( ) , ErrorCode :: ParseError . message ( ) ) . with_reason ( reason)
9299 }
93100
94- pub fn invalid_address_format ( field : & str , address : & str , expected_format : & str ) -> Self {
95- Self :: new ( INVALID_ADDRESS_FORMAT_CODE , "Invalid address format" )
101+ pub fn invalid_params ( field : & str , reason : & str ) -> Self {
102+ Self :: new ( ErrorCode :: InvalidParams . code ( ) , ErrorCode :: InvalidParams . message ( ) )
96103 . with_field ( field)
97- . with_received ( address. to_string ( ) )
98- . with_expected ( expected_format)
99- . with_suggestion ( "Ensure the address follows the correct format" )
104+ . with_reason ( reason)
100105 }
101106
102- pub fn invalid_amount ( field : & str , amount : & str , reason : & str ) -> Self {
103- Self :: new ( INVALID_AMOUNT_CODE , "Invalid amount value" )
104- . with_field ( field)
105- . with_received ( amount. to_string ( ) )
106- . with_expected ( "Positive number within valid range" )
107- . with_suggestion ( reason)
108- }
109-
110- pub fn invalid_hex_format ( field : & str , value : & str , expected_length : Option < usize > ) -> Self {
111- let expected = if let Some ( len) = expected_length {
112- format ! ( "0x-prefixed hex string of {} bytes" , len)
113- } else {
114- "Valid hexadecimal string" . to_string ( )
115- } ;
116-
117- Self :: new ( INVALID_HEX_FORMAT_CODE , "Invalid hexadecimal format" )
118- . with_field ( field)
119- . with_received ( value. to_string ( ) )
120- . with_expected ( expected)
121- . with_suggestion ( "Check that the value is properly hex-encoded" )
107+ pub fn invalid_backend_response < T : Codec > ( response : & ApiResponse < T > , op : & str ) -> Self {
108+ Self :: new ( INVALID_BACKEND_RESPONSE_CODE , "Invalid backend response" )
109+ . with_field ( op)
110+ . with_backend_response ( response. code as i32 , response. message . to_owned ( ) )
122111 }
123112
124- pub fn account_parse_error ( account : & str , error : & str ) -> Self {
125- Self :: new ( ACCOUNT_PARSE_ERROR_CODE , "Failed to parse account identifier" )
126- . with_field ( "omni_account" )
127- . with_received ( account. to_string ( ) )
128- . with_expected ( "Valid 32-byte account identifier" )
129- . with_suggestion ( format ! ( "Error: {}" , error) )
113+ pub fn invalid_chain_id ( chain_id : u64 ) -> Self {
114+ let supported: Vec < u64 > =
115+ crate :: config:: SUPPORTED_EVM_CHAINS . iter ( ) . map ( |& c| c as u64 ) . collect ( ) ;
116+ Self :: invalid_params (
117+ "chain_id" ,
118+ & format ! ( "invalid chain_id: {}, expected one of {:?}" , chain_id, supported) ,
119+ )
130120 }
131121
132- pub fn unexpected_response_type ( expected : & str , received : & str ) -> Self {
133- Self :: new ( UNEXPECTED_RESPONSE_TYPE_CODE , "Unexpected response type from service" )
134- . with_expected ( expected)
135- . with_received ( received)
136- . with_suggestion ( "This is likely an internal error. Please contact support." )
137- }
138-
139- pub fn signer_service_error ( operation : & str , error : & str ) -> Self {
140- Self :: new ( SIGNER_SERVICE_ERROR_CODE , format ! ( "Signer service error during {}" , operation) )
141- . with_suggestion ( format ! ( "Signer error: {}" , error) )
122+ pub fn signer_service_error ( ) -> Self {
123+ Self :: new ( SIGNER_SERVICE_ERROR_CODE , "Signer service error" )
142124 }
143125
144126 pub fn email_service_error ( email : & str ) -> Self {
@@ -148,35 +130,30 @@ impl DetailedError {
148130 . with_suggestion ( "Failed to send verification email. Please try again later." )
149131 }
150132
151- pub fn storage_error ( operation : & str ) -> Self {
152- Self :: new ( STORAGE_SERVICE_ERROR_CODE , format ! ( "Storage service error during {}" , operation) )
153- . with_suggestion ( "Storage operation failed. Please try again later." )
133+ pub fn storage_service_error ( op : & str ) -> Self {
134+ Self :: new ( STORAGE_SERVICE_ERROR_CODE , format ! ( "Storage service error in {}" , op) )
154135 }
155136
156- // Native task error factory methods
157- pub fn chain_not_supported ( chain_id : u64 ) -> Self {
158- // Get supported chains from config
159- use crate :: config:: SUPPORTED_EVM_CHAINS ;
160- let supported: Vec < u64 > = SUPPORTED_EVM_CHAINS . iter ( ) . map ( |& c| c as u64 ) . collect ( ) ;
137+ pub fn pumpx_service_error ( op : & str , reason : impl Into < String > ) -> Self {
138+ Self :: new ( PUMPX_SERVICE_ERROR_CODE , format ! ( "Pumpx service error in {}" , op) )
139+ . with_reason ( reason)
140+ }
161141
162- Self :: new ( INVALID_CHAIN_ID_CODE , "Chain not supported" )
163- . with_field ( "chain_id" )
164- . with_received ( chain_id. to_string ( ) )
165- . with_expected ( format ! ( "One of: {:?}" , supported) )
166- . with_suggestion ( "Please use a supported chain ID" )
142+ pub fn wildmeta_service_error ( op : & str ) -> Self {
143+ Self :: new ( WILDMETA_SERVICE_ERROR_CODE , format ! ( "Wildmeta service error in {}" , op) )
167144 }
168145
169- pub fn invalid_user_operation_error ( description : & str ) -> Self {
170- Self :: new ( INVALID_USER_OPERATION_CODE , description )
146+ pub fn invalid_user_op ( reason : & str ) -> Self {
147+ Self :: new ( INVALID_USEROP_CODE , "Invalid UserOp" ) . with_received ( reason )
171148 }
172149
173150 pub fn gas_estimation_failed ( ) -> Self {
174- Self :: new ( GAS_ESTIMATION_FAILED_CODE , "Unable to estimate gas for operation" )
175- . with_suggestion ( "Please check the user operation parameters and try again" )
151+ Self :: new ( GAS_ESTIMATION_FAILED_CODE , "Gas estimaton failed" )
176152 }
153+ }
177154
178- pub fn signature_service_unavailable ( ) -> Self {
179- Self :: new ( SIGNATURE_SERVICE_UNAVAILABLE_CODE , "Signature service temporarily unavailable" )
180- . with_suggestion ( "Please try again in a few moments" )
155+ impl From < DetailedError > for ErrorObjectOwned {
156+ fn from ( error : DetailedError ) -> Self {
157+ error . to_rpc_error ( )
181158 }
182159}
0 commit comments