Skip to main content

Problem

Struct Problem 

Source
#[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
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional 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: StatusCode

The 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

Source

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.

Source

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.

Source

pub fn with_detail(self, detail: impl Into<String>) -> Self

Sets the occurrence-specific explanation.

Source

pub fn with_instance(self, instance: impl Into<String>) -> Self

Sets the URI identifying this occurrence.

Source

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§

Source§

impl Clone for Problem

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Problem

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

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.

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

Writes this value as a response.
Source§

impl PartialEq for Problem

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

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§

fn schema(registry: &mut Registry) -> OpenApiSchema

Produces the schema body for this type. Read more
Source§

fn name() -> Option<ComponentName>

The component name this type is registered under, if it has one. Read more
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.

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.

Source§

fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Problem

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Provides<T> for T
where T: Clone,

Source§

fn provide(&self) -> T

Supplies the value for one request.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more