1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! Render 404, 419 and 500 as Inertia pages instead of RFC 9457 documents.
//!
//! # Why this is a layer and not a route
//!
//! A catch-all route would shadow the static-file fallback, so every asset
//! would 404. A response-inspecting layer leaves routing alone and only acts
//! on a status that has already been decided.
//!
//! # Why it renders instead of attaching a `PendingPage`
//!
//! Returning `Page<T>` from here would work, but the Inertia layer treats the
//! render's status as authoritative and discards the one the response
//! arrived with -- a 404 would reach the browser as a 200. Rendering through
//! the [`Inertia`] extractor directly leaves the status in this layer's
//! hands, so the page and the status code agree.
//!
//! # Where this sits
//!
//! Installed with `.layer(..)`, which the pipeline places *inside* the
//! Inertia layer. That is what makes the [`Inertia`] extractor resolvable
//! here: the layer above has already inserted the config and the parsed
//! request into extensions.
use Request;
use ACCEPT;
use Next;
use *;
/// The component rendered for a `404`.
const NOT_FOUND: &str = "errors/404";
/// The component rendered for a `419`.
const PAGE_EXPIRED: &str = "errors/419";
/// The component rendered for any `5xx`.
const SERVER_ERROR: &str = "errors/500";
/// The `419 Page Expired` status. Not in `StatusCode`'s constant set because
/// it is not an IANA-registered code; it is the convention the Inertia
/// ecosystem uses for a stale CSRF token.
const PAGE_EXPIRED_STATUS: u16 = 419;
/// Replace an error response with the matching Inertia page.
///
/// Requests that did not ask for HTML -- an API client, a fetch for a missing
/// asset -- keep the RFC 9457 body the error mapping produced. A render
/// failure also falls back to the original response: an error page that
/// itself errors must not replace a correct status with a confusing one.
pub async
/// True when the caller is a browser navigation or an Inertia visit.
///
/// An Inertia visit is checked separately because its `Accept` is
/// `application/json`: the client asks for the page object, not a document,
/// and still expects the error page.