diff --git a/web3_proxy/src/errors.rs b/web3_proxy/src/errors.rs index 493d6420..15008438 100644 --- a/web3_proxy/src/errors.rs +++ b/web3_proxy/src/errors.rs @@ -98,6 +98,9 @@ pub enum Web3ProxyError { #[display(fmt = "{:?}", _0)] #[error(ignore)] JsonRpcErrorData(JsonRpcErrorData), + #[from(ignore)] + #[display(fmt = "{}", _0)] + MdbxPanic(String, Cow<'static, str>), NoBlockNumberOrHash, NoBlocksKnown, NoConsensusHeadBlock, @@ -199,6 +202,7 @@ impl Web3ProxyError { /// turn the error into an axum response. /// + /// TODO? change to `to_response_parts(self)` pub fn as_response_parts(&self) -> (StatusCode, JsonRpcResponseEnum>) { // TODO: include a unique request id in the data let (code, err): (StatusCode, JsonRpcErrorData) = match self { @@ -642,6 +646,20 @@ impl Web3ProxyError { // TODO: do this without clone? the Arc needed it though (StatusCode::OK, jsonrpc_error_data.clone()) } + Self::MdbxPanic(rpc, msg) => { + error!(%msg, "mdbx panic"); + + // TODO: this is bad enough that we should send something to pager duty + + ( + StatusCode::INTERNAL_SERVER_ERROR, + JsonRpcErrorData { + message: "mdbx panic".into(), + code: StatusCode::INTERNAL_SERVER_ERROR.as_u16().into(), + data: Some(serde_json::Value::String(msg.to_string())), + }, + ) + } Self::MethodNotFound(method) => { warn!("MethodNotFound: {}", method); ( diff --git a/web3_proxy/src/rpcs/request.rs b/web3_proxy/src/rpcs/request.rs index 3853431e..96af7c73 100644 --- a/web3_proxy/src/rpcs/request.rs +++ b/web3_proxy/src/rpcs/request.rs @@ -383,17 +383,24 @@ impl OpenRequestHandle { match error.code { -32000 => { - // TODO: regex? - let archive_prefixes = [ - "header not found", - "header for hash not found", - "missing trie node", - ]; - for prefix in archive_prefixes { - if error.message.starts_with(prefix) { - // TODO: what error? - response = Err(Web3ProxyError::NoBlockNumberOrHash); - break; + if error.message.contains("MDBX_PANIC:") { + response = Err(Web3ProxyError::MdbxPanic( + self.connection_name(), + error.message.clone(), + )); + } else { + // TODO: regex? + let archive_prefixes = [ + "header not found", + "header for hash not found", + "missing trie node", + ]; + for prefix in archive_prefixes { + if error.message.starts_with(prefix) { + // TODO: what error? + response = Err(Web3ProxyError::NoBlockNumberOrHash); + break; + } } } }