better error handling for ws

This commit is contained in:
Rory Neithinger 2023-03-19 19:14:46 -07:00
parent beac7ee017
commit 1493d73386
3 changed files with 22 additions and 22 deletions

@ -2,6 +2,7 @@
use super::Web3ProxyApp; use super::Web3ProxyApp;
use crate::frontend::authorization::{Authorization, RequestMetadata}; use crate::frontend::authorization::{Authorization, RequestMetadata};
use crate::frontend::errors::Web3ProxyResult;
use crate::jsonrpc::JsonRpcForwardedResponse; use crate::jsonrpc::JsonRpcForwardedResponse;
use crate::jsonrpc::JsonRpcRequest; use crate::jsonrpc::JsonRpcRequest;
use crate::rpcs::transactions::TxStatus; use crate::rpcs::transactions::TxStatus;
@ -27,7 +28,7 @@ impl Web3ProxyApp {
subscription_count: &'a AtomicUsize, 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 // 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<Message>, response_sender: flume::Sender<Message>,
) -> anyhow::Result<(AbortHandle, JsonRpcForwardedResponse)> { ) -> Web3ProxyResult<(AbortHandle, JsonRpcForwardedResponse)> {
// TODO: this is not efficient // TODO: this is not efficient
let request_bytes = serde_json::to_string(&request_json) let request_bytes = serde_json::to_string(&request_json)
.context("finding request size")? .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? // TODO: do something with subscription_join_handle?

@ -85,6 +85,7 @@ pub enum Web3ProxyError {
#[error(ignore)] #[error(ignore)]
UserAgentNotAllowed(headers::UserAgent), UserAgentNotAllowed(headers::UserAgent),
WatchRecvError(tokio::sync::watch::error::RecvError), WatchRecvError(tokio::sync::watch::error::RecvError),
WebsocketOnly,
} }
impl Web3ProxyError { 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,
),
)
}
} }
} }
} }

@ -7,6 +7,7 @@ use super::errors::{Web3ProxyError, Web3ProxyResponse};
use crate::stats::RpcQueryStats; use crate::stats::RpcQueryStats;
use crate::{ use crate::{
app::Web3ProxyApp, app::Web3ProxyApp,
frontend::errors::Web3ProxyResult,
jsonrpc::{JsonRpcForwardedResponse, JsonRpcForwardedResponseEnum, JsonRpcRequest}, jsonrpc::{JsonRpcForwardedResponse, JsonRpcForwardedResponseEnum, JsonRpcRequest},
}; };
use axum::headers::{Origin, Referer, UserAgent}; use axum::headers::{Origin, Referer, UserAgent};
@ -26,7 +27,7 @@ use futures::{
use handlebars::Handlebars; use handlebars::Handlebars;
use hashbrown::HashMap; use hashbrown::HashMap;
use http::StatusCode; use http::StatusCode;
use log::{error, info, trace, warn}; use log::{info, trace, warn};
use serde_json::json; use serde_json::json;
use serde_json::value::to_raw_value; use serde_json::value::to_raw_value;
use std::sync::Arc; use std::sync::Arc;
@ -112,11 +113,7 @@ async fn _websocket_handler(
// this is not a websocket. redirect to a friendly page // this is not a websocket. redirect to a friendly page
Ok(Redirect::permanent(redirect).into_response()) Ok(Redirect::permanent(redirect).into_response())
} else { } else {
// TODO: do not use an anyhow error. send the user a 400 Err(Web3ProxyError::WebsocketOnly)
Err(
anyhow::anyhow!("redirect_public_url not set. only websockets work here")
.into(),
)
} }
} }
} }
@ -341,7 +338,7 @@ async fn handle_socket_payload(
Ok(json_request) => { Ok(json_request) => {
let id = json_request.id.clone(); let id = json_request.id.clone();
let response: anyhow::Result<JsonRpcForwardedResponseEnum> = match &json_request.method let response: Web3ProxyResult<JsonRpcForwardedResponseEnum> = match &json_request.method
[..] [..]
{ {
"eth_subscribe" => { "eth_subscribe" => {
@ -417,16 +414,7 @@ async fn handle_socket_payload(
_ => app _ => app
.proxy_web3_rpc(authorization.clone(), json_request.into()) .proxy_web3_rpc(authorization.clone(), json_request.into())
.await .await
.map_or_else( .map(|(response, _)| response),
|err| match err {
Web3ProxyError::Anyhow(err) => Err(err),
_ => {
error!("handle this better! {:?}", err);
Err(anyhow::anyhow!("unexpected error! {:?}", err))
}
},
|(response, _)| Ok(response),
),
}; };
(id, response) (id, response)
@ -442,9 +430,8 @@ async fn handle_socket_payload(
let response_str = match response { let response_str = match response {
Ok(x) => serde_json::to_string(&x).expect("to_string should always work here"), Ok(x) => serde_json::to_string(&x).expect("to_string should always work here"),
Err(err) => { Err(err) => {
// we have an anyhow error. turn it into a response let (_, mut response) = err.into_response_parts();
let response = JsonRpcForwardedResponse::from_anyhow_error(err, None, Some(id)); response.id = id;
serde_json::to_string(&response).expect("to_string should always work here") serde_json::to_string(&response).expect("to_string should always work here")
} }
}; };