From 1493d73386891b75930b07e1fd0c281ffa4582c1 Mon Sep 17 00:00:00 2001 From: Rory Neithinger Date: Sun, 19 Mar 2023 19:14:46 -0700 Subject: [PATCH] better error handling for ws --- web3_proxy/src/app/ws.rs | 5 +++-- web3_proxy/src/frontend/errors.rs | 12 +++++++++++ web3_proxy/src/frontend/rpc_proxy_ws.rs | 27 +++++++------------------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/web3_proxy/src/app/ws.rs b/web3_proxy/src/app/ws.rs index 79617f7b..2366ab31 100644 --- a/web3_proxy/src/app/ws.rs +++ b/web3_proxy/src/app/ws.rs @@ -2,6 +2,7 @@ use super::Web3ProxyApp; use crate::frontend::authorization::{Authorization, RequestMetadata}; +use crate::frontend::errors::Web3ProxyResult; use crate::jsonrpc::JsonRpcForwardedResponse; use crate::jsonrpc::JsonRpcRequest; use crate::rpcs::transactions::TxStatus; @@ -27,7 +28,7 @@ impl Web3ProxyApp { subscription_count: &'a AtomicUsize, // TODO: taking a sender for Message instead of the exact json we are planning to send feels wrong, but its easier for now response_sender: flume::Sender, - ) -> anyhow::Result<(AbortHandle, JsonRpcForwardedResponse)> { + ) -> Web3ProxyResult<(AbortHandle, JsonRpcForwardedResponse)> { // TODO: this is not efficient let request_bytes = serde_json::to_string(&request_json) .context("finding request size")? @@ -341,7 +342,7 @@ impl Web3ProxyApp { ); }); } - _ => return Err(anyhow::anyhow!("unimplemented")), + _ => return Err(anyhow::anyhow!("unimplemented").into()), } // TODO: do something with subscription_join_handle? diff --git a/web3_proxy/src/frontend/errors.rs b/web3_proxy/src/frontend/errors.rs index 8acd662c..0e4356a8 100644 --- a/web3_proxy/src/frontend/errors.rs +++ b/web3_proxy/src/frontend/errors.rs @@ -85,6 +85,7 @@ pub enum Web3ProxyError { #[error(ignore)] UserAgentNotAllowed(headers::UserAgent), WatchRecvError(tokio::sync::watch::error::RecvError), + WebsocketOnly, } impl Web3ProxyError { @@ -517,6 +518,17 @@ impl Web3ProxyError { ), ) } + Self::WebsocketOnly => { + warn!("WebsocketOnly"); + ( + StatusCode::BAD_REQUEST, + JsonRpcForwardedResponse::from_str( + "redirect_public_url not set. only websockets work here", + Some(StatusCode::BAD_REQUEST.as_u16().into()), + None, + ), + ) + } } } } diff --git a/web3_proxy/src/frontend/rpc_proxy_ws.rs b/web3_proxy/src/frontend/rpc_proxy_ws.rs index 9f249555..df186414 100644 --- a/web3_proxy/src/frontend/rpc_proxy_ws.rs +++ b/web3_proxy/src/frontend/rpc_proxy_ws.rs @@ -7,6 +7,7 @@ use super::errors::{Web3ProxyError, Web3ProxyResponse}; use crate::stats::RpcQueryStats; use crate::{ app::Web3ProxyApp, + frontend::errors::Web3ProxyResult, jsonrpc::{JsonRpcForwardedResponse, JsonRpcForwardedResponseEnum, JsonRpcRequest}, }; use axum::headers::{Origin, Referer, UserAgent}; @@ -26,7 +27,7 @@ use futures::{ use handlebars::Handlebars; use hashbrown::HashMap; use http::StatusCode; -use log::{error, info, trace, warn}; +use log::{info, trace, warn}; use serde_json::json; use serde_json::value::to_raw_value; use std::sync::Arc; @@ -112,11 +113,7 @@ async fn _websocket_handler( // this is not a websocket. redirect to a friendly page Ok(Redirect::permanent(redirect).into_response()) } else { - // TODO: do not use an anyhow error. send the user a 400 - Err( - anyhow::anyhow!("redirect_public_url not set. only websockets work here") - .into(), - ) + Err(Web3ProxyError::WebsocketOnly) } } } @@ -341,7 +338,7 @@ async fn handle_socket_payload( Ok(json_request) => { let id = json_request.id.clone(); - let response: anyhow::Result = match &json_request.method + let response: Web3ProxyResult = match &json_request.method [..] { "eth_subscribe" => { @@ -417,16 +414,7 @@ async fn handle_socket_payload( _ => app .proxy_web3_rpc(authorization.clone(), json_request.into()) .await - .map_or_else( - |err| match err { - Web3ProxyError::Anyhow(err) => Err(err), - _ => { - error!("handle this better! {:?}", err); - Err(anyhow::anyhow!("unexpected error! {:?}", err)) - } - }, - |(response, _)| Ok(response), - ), + .map(|(response, _)| response), }; (id, response) @@ -442,9 +430,8 @@ async fn handle_socket_payload( let response_str = match response { Ok(x) => serde_json::to_string(&x).expect("to_string should always work here"), Err(err) => { - // we have an anyhow error. turn it into a response - let response = JsonRpcForwardedResponse::from_anyhow_error(err, None, Some(id)); - + let (_, mut response) = err.into_response_parts(); + response.id = id; serde_json::to_string(&response).expect("to_string should always work here") } };