When debugging an Actix Web 4.2.1 Rust application, every error message gets multiplied 10 times (= my number of physical CPU cores). How do I get it to show the error only once?
use actix_web::*;
#[get("/")]
async fn panic() -> impl Responder {
if true {panic!("this error message is shown too many times");}
HttpResponse::Ok().body("Hello world!")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(panic)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
After opening localhost:8080 in a browser, the Rust application above prints the following:
$ cargo run
Compiling actitest v0.1.0 (/tmp/actitest)
Finished dev [unoptimized + debuginfo] target(s) in 1.52s
Running `target/debug/actitest`
thread 'actix-rt|system:0|arbiter:0' panicked at 'this error message is shown too many times', src/main.rs:5:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'actix-rt|system:0|arbiter:1' panicked at 'this error message is shown too many times', src/main.rs:5:14
thread 'actix-rt|system:0|arbiter:2' panicked at 'this error message is shown too many times', src/main.rs:5:14
thread 'actix-rt|system:0|arbiter:3' panicked at 'this error message is shown too many times', src/main.rs:5:14
thread 'actix-rt|system:0|arbiter:4' panicked at 'this error message is shown too many times', src/main.rs:5:14
thread 'actix-rt|system:0|arbiter:5' panicked at 'this error message is shown too many times', src/main.rs:5:14
thread 'actix-rt|system:0|arbiter:6' panicked at 'this error message is shown too many times', src/main.rs:5:14
thread 'actix-rt|system:0|arbiter:7' panicked at 'this error message is shown too many times', src/main.rs:5:14
thread 'actix-rt|system:0|arbiter:8' panicked at 'this error message is shown too many times', src/main.rs:5:14
thread 'actix-rt|system:0|arbiter:9' panicked at 'this error message is shown too many times', src/main.rs:5:14
How can I get this message to be shown a single time only?
You get multiple messages because your browser tries to be helpful and calls the endpoint multiple times assuming a spurious failure might have occured. Thus you are in fact getting the error multiple times until all arbiters die and have to be generated wich takes a short while.
To get around this you could use a less 'smart' tool to access the endpoint:
curl localhost:8080/
will only produce the error once.
Related
Referenced Axum documentation: docs.rs
Hello all, I am trying to create a simple file upload using HTML5 forms and Rust Axum.
The issue is that, while any normal file works, larger files (particularly video files) which I want to upload are too large. Axum (subsequently Tokio) panics because the Field size is too large for the file upload.
I can't seem to find any helpful information about either expanding the stream limit.
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="filename" accept="video/mp4">
<input type="submit" value="Upload video">
</form>
async fn upload(mut multipart: Multipart) {
while let Some(mut field) = multipart.next_field().await.unwrap() {
let name = field.name().unwrap().to_string();
let data = field.bytes().await.unwrap();
println!("Length of `{}` is {} bytes", name, data.len());
}
}
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: MultipartError { source: failed to read stream: failed to read stream: length limit exceeded }', src/main.rs:84:40
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: MultipartError { source: failed to read stream: failed to read stream: length limit exceeded }', src/main.rs:84:40
thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: MultipartError { source: failed to read stream: failed to read stream: length limit exceeded }', src/main.rs:84:40
To not take away from the primary part of this code, I have omitted the router, but its application is: .route("/upload", post(upload)) as per the example shown in the Axum documentation.
Quick note: to enable Multipart file uploads, you must add the Cargo feature flag "multipart" with Axum.
Any help is appreciated. Thank you.
Have you tried using Axum's DefaultBodyLimit service?
use axum::{
Router,
routing::post,
body::Body,
extract::{DefaultBodyLimit, RawBody},
http::Request,
};
let app = Router::new()
.route(
"/",
// even with `DefaultBodyLimit` the request body is still just `Body`
post(|request: Request<Body>| async {}),
)
.layer(DefaultBodyLimit::max(1024));
I found this example here
So I have a multi-threading program in Rust, which sends Get Requests to my Website, and I'm wondering how I can detect a ConnectionReset.
What I'm trying to do is, after the request, check if there was a ConnectionReset, and if there was, wait for a minute, so the thread doesn't panic
The code I'm using right now
let mut req = reqwest::get(&url).unwrap();
And after that was executed I want to check if there's a ConnectionReset, and then println ("Connection Error"), instead of having the thread panic.
The Error, that I want to detect
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value:
Error { kind: Io(Custom { kind: Other, error: Os { code: 10054, kind: ConnectionReset,
message: "An existing connection was forcibly closed by the remote host." } }),
url: Some("https://tayhay.vip") }', src\main.rs:22:43
I also read something about std::panic::catch_unwind, but I am not sure if that's the right way to go.
.unwrap means literally: "panic in case of error". If you don't want to panic, you will have to handle the error yourself. You have three solutions here depending on code you haven't shown us:
Propagate the error up with the ? operator and let the calling function handle it.
Have some default value ready to use (or create on the fly) in case of error:
let mut req = reqwest::get (&url).unwrap_or (default);
or
let mut req = reqwest::get (&url).unwrap_or_else (|_| { default });
(this probably doesn't apply in this specific case since I don't know what would make a sensible default here, but it applies in other error handling situations).
Have some specific error handling code:
match reqwest::get (&url) {
Ok (mut req) => { /* Process the request */ },
Err (e) => { /* Handle the error */ },
}
For more details, the Rust book has a full chapter on error handling.
Please find the code I try to run below.
extern crate image;
use image::GenericImageView;
fn main() {
println!("Hello, world!");
// Use the open function to load an image from a Path.
// `open` returns a `DynamicImage` on success.
let img = image::open(
"C:/Users/hp/Desktop/Multiprocessor real-time scheduling/Project2/data/aLIEz.jpg",
)
.unwrap();
// The dimensions method returns the images width and height.
println!("dimensions {:?}", img.dimensions());
// The color method returns the image's `ColorType`.
println!("{:?}", img.color());
// Write the contents of this image to the Writer in PNG format.
img.save("C:/Users/hp/Desktop/Multiprocessor real-time scheduling/Project2/data/test.png")
.unwrap();
}
The error I want to solve (in the last line img.save) :
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: IoError(Os { code: 5, kind: PermissionDenied, message: "Accès refusé." })', src\main.rs:18:96
This is the sample hello world program from the Tokio documentation .
use tokio::prelude::*;
#[tokio::main]
async fn main() {
let mut stream = TcpStream::connect("127.0.0.1:6142").await.unwrap();
println!("created stream");
let result = stream.write(b"hello world\n").await;
println!("wrote to stream; success={:?}", result.is_ok());
}
Which gives me this error:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 10061, kind: ConnectionRefused, message: "No connection could be made because the target machine actively refused it." }', src\libcore\result.rs:1165:5
stack backtrace:
.
.
.
How can I fix it?
You seemingly didn't follow the instructions for the hello world, thus you get an error because there's no server listening:
Install socat, which is a network utility that we’ll use to simulate a server. Then type the following command to print out everything that is received on port 6142 (a somewhat arbitrary number we have chosen for this example):
socat TCP-LISTEN:6142,fork stdout
Can I register the same TcpListener on multiple mio Poll objects (one Poll per thread for a multi-threaded server)?
When I try, I get the error:
thread 'main' panicked at 'called Result::unwrap() on an Err
value: Error { repr: Custom(Custom { kind: Other, error:
StringError("socket already registered") }) }',
src/libcore/result.rs:788
Is this intended behavior?