Skip to content

Instantly share code, notes, and snippets.

@koivunej
Created June 13, 2022 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koivunej/8eeb6cf7cd5cfcae3696eb458a10297e to your computer and use it in GitHub Desktop.
Save koivunej/8eeb6cf7cd5cfcae3696eb458a10297e to your computer and use it in GitHub Desktop.
jsonrpsee tokio::task::JoinError handling reproducer
[package]
name = "jsonrpsee_todo"
version = "0.1.0"
edition = "2021"
[dependencies]
jsonrpsee = { version = "0.13", features = ["full"] }
tokio = { version = "1", features = ["full"] }
serde_json = "*"
hyper = "*"
reqwest = {version = "*", features = ["json"] }
use std::error::Error;
#[tokio::main]
async fn main() {
let server = jsonrpsee::http_server::HttpServerBuilder::default()
.build("127.0.0.1:0")
.await
.expect("should had started the server");
let local_addr = server
.local_addr()
.expect("should have the real listening address");
println!("bound at {}", local_addr);
let mut module = jsonrpsee::RpcModule::new(());
module
.register_blocking_method(
"todo",
|_params, _ctx| -> Result<serde_json::Value, jsonrpsee::core::Error> {
todo!("this causes a joinerror");
},
)
.expect("blocking method should register fine");
let server_handle = server.start(module).expect("should start to serve");
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("--- server should now be ready, didn't see other way than to sleep for it");
let client = reqwest::Client::new();
let err = client
.post(format!("http://{}", local_addr))
.json(&serde_json::json! {{
"jsonrpc": "2.0",
"id": "1",
"method": "todo",
}})
.fetch_mode_no_cors()
.send()
.await
.expect_err("request should fail");
println!("--- request made");
server_handle.stop().expect("should stop ok");
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
println!("--- assumed server stopped");
match err.source() {
Some(inner) if err.is_request() => {
if let Some(inner) = inner.downcast_ref::<hyper::Error>() {
assert!(inner.is_incomplete_message());
println!("got expected {inner:?}");
return;
}
}
_ => {}
}
todo!("unexpected inner error in {err:#?}");
}
@koivunej
Copy link
Author

Expected output:

bound at 127.0.0.1:39845
--- server should now be ready, didn't see other way than to sleep for it
thread 'tokio-runtime-worker' panicked at 'not yet implemented: this causes a joinerror', src/main.rs:22:17
thread 'tokio-runtime-worker' panicked at 'Sender is still alive managed by us above; qed', /home/joonas/.cargo/registry/src/github.com-1ecc6299db9ec823/jsonrpsee-http-server-0.13.1/src/server.rs:712:25
--- request made
--- assumed server stopped
got expected hyper::Error(IncompleteMessage)

which is same as:

$ echo '{"jsonrpc": "2.0", "id": "1", "method": "todo"}' | curl -vv -X POST -H 'content-type: application/json' -d @- http://127.0.0.1:37071
*   Trying 127.0.0.1:37071...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 37071 (#0)
> POST / HTTP/1.1
> Host: 127.0.0.1:37071
> User-Agent: curl/7.68.0
> Accept: */*
> content-type: application/json
> Content-Length: 47
>
* upload completely sent off: 47 out of 47 bytes
* Empty reply from server
* Connection #0 to host 127.0.0.1 left intact
curl: (52) Empty reply from server

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment