turul_a2a/middleware/error.rs
1//! Middleware error types — transport-level only, never in A2aError.
2
3/// Middleware errors produce HTTP responses directly via the Tower layer.
4/// These never become A2aError variants or JSON-RPC error objects.
5#[derive(Debug, Clone)]
6#[non_exhaustive]
7pub enum MiddlewareError {
8 /// 401 — no credentials or invalid credentials.
9 Unauthenticated(String),
10 /// 401 with WWW-Authenticate challenge header.
11 HttpChallenge {
12 status: u16,
13 www_authenticate: String,
14 },
15 /// 403 — credentials valid but insufficient permissions.
16 Forbidden(String),
17 /// 500 — internal middleware failure (fatal, short-circuits AnyOf).
18 Internal(String),
19}
20
21impl MiddlewareError {
22 /// Precedence for AnyOfMiddleware failure aggregation.
23 /// Higher = takes priority when selecting which error to surface.
24 pub(crate) fn precedence(&self) -> u8 {
25 match self {
26 Self::Forbidden(_) => 3,
27 Self::HttpChallenge { .. } => 2,
28 Self::Unauthenticated(_) => 1,
29 Self::Internal(_) => 0, // should never participate in aggregation (short-circuits)
30 }
31 }
32
33 pub fn http_status(&self) -> u16 {
34 match self {
35 Self::Unauthenticated(_) | Self::HttpChallenge { .. } => 401,
36 Self::Forbidden(_) => 403,
37 Self::Internal(_) => 500,
38 }
39 }
40}