Skip to content

Commit b767a0e

Browse files
authored
Problem details updates (#130)
* Problem details updates * added app,route/group helpers for registering problem details * updates for problem! macro
1 parent e119b5a commit b767a0e

File tree

7 files changed

+515
-28
lines changed

7 files changed

+515
-28
lines changed

examples/global_error_handler/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ publish = false
88
tokio = "1.46.1"
99
tracing = "0.1.41"
1010
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
11-
volga = { path = "../../volga", features = ["tracing","problem-details"] }
11+
volga = { path = "../../volga", features = ["tracing"] }
1212

1313
[lints]
1414
workspace = true

examples/global_error_handler/src/main.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! cargo run -p global_error_handler
55
//! ```
66
7-
use volga::{App, problem};
7+
use volga::{App, status};
88
use std::io::Error;
99
use tracing_subscriber::prelude::*;
1010

@@ -27,13 +27,8 @@ async fn main() -> std::io::Result<()> {
2727
// Enabling global error handler
2828
app.map_err(|error: volga::error::Error| async move {
2929
tracing::error!("{:?}", error);
30-
let (status, instance, err) = error.into_parts();
31-
problem! {
32-
"status": status.as_u16(),
33-
"detail": (err.to_string()),
34-
"instance": instance,
35-
}
36-
});
30+
status!(error.status.as_u16(), "{error}")
31+
});
3732

3833
app.run().await
3934
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "problem_details"
3+
version = "0.1.0"
4+
edition = "2024"
5+
publish = false
6+
7+
[dependencies]
8+
tokio = "1.46.1"
9+
tracing = "0.1.41"
10+
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
11+
volga = { path = "../../volga", features = ["tracing","problem-details"] }
12+
serde = { version = "1.0.219", features = ["serde_derive"] }
13+
14+
[lints]
15+
workspace = true
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//! Run with:
2+
//!
3+
//! ```no_rust
4+
//! cargo run -p problem_details
5+
//! ```
6+
7+
use volga::{App, error::Problem};
8+
use std::io::Error;
9+
use serde::Serialize;
10+
use tracing_subscriber::prelude::*;
11+
12+
#[tokio::main]
13+
async fn main() -> std::io::Result<()> {
14+
tracing_subscriber::registry()
15+
.with(tracing_subscriber::fmt::layer())
16+
.init();
17+
18+
let mut app = App::new()
19+
.with_tracing(|tracing| tracing.with_header());
20+
21+
app.use_tracing();
22+
23+
// Enabling global error handler that produces
24+
// error responses in Problem details format
25+
app.use_problem_details();
26+
27+
app.map_get("/error", || async {
28+
tracing::trace!("producing error");
29+
Error::other("some error")
30+
});
31+
32+
app.map_get("/problem", || async {
33+
// Always producing a problem
34+
35+
Problem::new(400)
36+
.with_detail("Missing Parameter")
37+
.with_instance("/problem")
38+
.with_extensions(ValidationError {
39+
invalid_params: vec![InvalidParam {
40+
name: "id".into(),
41+
reason: "The ID must be provided".into()
42+
}]
43+
})
44+
});
45+
46+
app.run().await
47+
}
48+
49+
#[derive(Default, Serialize)]
50+
struct ValidationError {
51+
#[serde(rename = "invalid-params")]
52+
invalid_params: Vec<InvalidParam>,
53+
}
54+
55+
#[derive(Default, Serialize)]
56+
struct InvalidParam {
57+
name: String,
58+
reason: String,
59+
}

volga/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ keywords = ["async", "server", "http", "web", "framework"]
1818
bytes = "1.11.0"
1919
futures-util = { version = "0.3.31", default-features = false, features = ["alloc"] }
2020
http-body-util = "0.1.3"
21-
itoa = "1.0.15"
21+
itoa = "1.0.16"
2222
indexmap = "2.12.1"
2323
memchr = "2.7.6"
2424
mime = "0.3.17"
@@ -96,7 +96,7 @@ di = ["dep:volga-di"]
9696
macros = ["dep:volga-macros"]
9797
middleware = []
9898
multipart = ["dep:multer"]
99-
problem-details = []
99+
problem-details = ["serde/derive"]
100100
static-files = ["dep:chrono", "dep:handlebars", "dep:sha1"]
101101
tls = ["middleware", "dep:tokio-rustls", "tokio-rustls?/tls12", "tokio-rustls?/ring"]
102102
tracing = ["middleware", "dep:tracing"]

volga/src/error.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub use self::{
2525
};
2626

2727
#[cfg(feature = "problem-details")]
28-
pub use self::problem::Problem;
28+
pub use self::problem::{Problem, ProblemDetails};
2929

3030
pub mod handler;
3131
pub mod fallback;
@@ -201,7 +201,7 @@ impl App {
201201
///
202202
/// # Example
203203
/// ```no_run
204-
/// use volga::{App, error::Error, status};
204+
/// use volga::{App, error::Error, status};
205205
///
206206
/// # #[tokio::main]
207207
/// # async fn main() -> std::io::Result<()> {

0 commit comments

Comments
 (0)