#[non_exhaustive]pub struct Problem {
pub type_uri: Cow<'static, str>,
pub title: Cow<'static, str>,
pub status: StatusCode,
pub detail: Option<String>,
pub instance: Option<String>,
pub extensions: BTreeMap<String, Value>,
}Expand description
An RFC 9457 problem detail.
The five registered members are typed; anything else goes in
extensions, which is how an error carries the
specifics a client needs to act on it — which field failed, which quota was
exceeded, when to retry.
§This is a representation, not a return type
Problem carries its status in a field, so a handler returning one would
choose that status at run time and no description could say which. It
therefore does not implement Responses, and
Result<T, Problem> does not compile:
fn returns<T: kynos::response::IntoResponse + kynos::response::Responses>() {}
returns::<Result<NoContent, Problem>>();This is anti-pattern 4 applied to errors, and the same reasoning that
keeps IntoResponse off StatusCode. Name an error type instead and let
#[derive(ApiError)] produce the problem, so the statuses the operation
advertises are a const rather than whatever the handler happened to build.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.type_uri: Cow<'static, str>A URI identifying the problem type.
Defaults to about:blank, which means “the status code is the whole
story”. Anything a client should branch on deserves a real URI.
title: Cow<'static, str>A short, human-readable summary of the problem type.
Should not change from occurrence to occurrence; put the specifics in
detail.
status: StatusCodeThe HTTP status code.
detail: Option<String>An explanation specific to this occurrence.
instance: Option<String>A URI identifying this specific occurrence.
extensions: BTreeMap<String, Value>Additional members, serialized alongside the registered ones.
Implementations§
Source§impl Problem
impl Problem
Sourcepub fn new(status: StatusCode) -> Self
pub fn new(status: StatusCode) -> Self
Creates a problem with about:blank as its type.
The title is the status code’s reason phrase, which is what RFC 9457 asks for when the type carries no semantics of its own.
Sourcepub fn of_type(
status: StatusCode,
type_uri: impl Into<Cow<'static, str>>,
title: impl Into<Cow<'static, str>>,
) -> Self
pub fn of_type( status: StatusCode, type_uri: impl Into<Cow<'static, str>>, title: impl Into<Cow<'static, str>>, ) -> Self
Creates a problem with an identifying type URI and title.
Sourcepub fn with_detail(self, detail: impl Into<String>) -> Self
pub fn with_detail(self, detail: impl Into<String>) -> Self
Sets the occurrence-specific explanation.
Sourcepub fn with_instance(self, instance: impl Into<String>) -> Self
pub fn with_instance(self, instance: impl Into<String>) -> Self
Sets the URI identifying this occurrence.
Sourcepub fn with_extension(
self,
key: impl Into<String>,
value: impl Into<Value>,
) -> Self
pub fn with_extension( self, key: impl Into<String>, value: impl Into<Value>, ) -> Self
Attaches an additional member.
A key naming one of the five registered members never reaches the wire:
an extension that shadowed type, title, status, detail or
instance would put two entries under one name.
Trait Implementations§
impl Flatten for Problem
Flattenable, so a problem type can carry its extension members as fields of its own.
The schema names the five registered members and admits every other one, so
from inside the carrying object’s allOf it marks every member evaluated and
constrains none it does not name. The five it names it does constrain, so a
member of the carrying object may not reuse type, title, status,
detail or instance.
Source§impl IntoResponse for Problem
A problem can be written, which is how every error reaches the wire: an
ApiError converts itself with IntoProblem and the result is rendered
here.
impl IntoResponse for Problem
A problem can be written, which is how every error reaches the wire: an
ApiError converts itself with IntoProblem and the result is rendered
here.
What it deliberately cannot do is Responses.
A handler’s return type needs both halves, so the missing one is what stops
Result<T, Problem> from compiling — see the type documentation for why
that matters.
Source§fn into_response(self) -> Response
fn into_response(self) -> Response
Source§impl Schema for Problem
The schema every error response references.
impl Schema for Problem
The schema every error response references.
Registered as a named component rather than inlined, because a document where each of a hundred operations repeats the same five-property object is one no reader will check.
Source§impl Serialize for Problem
Serialized by hand rather than derived: StatusCode is not
serde::Serialize, type_uri is written as RFC 9457’s type, and the
extension members are flattened alongside the registered ones rather than
nested under a field of their own.
impl Serialize for Problem
Serialized by hand rather than derived: StatusCode is not
serde::Serialize, type_uri is written as RFC 9457’s type, and the
extension members are flattened alongside the registered ones rather than
nested under a field of their own.
type and status are always written, which is what the schema declares as
required. title is omitted when empty, and detail and instance when
absent. An extension whose key names a registered member is dropped, since
one name cannot hold two values.