fastcgi_client/error.rs
1// Copyright 2022 jmjoy
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Error types and result type aliases for FastCGI operations.
16//!
17//! This module defines the error types that can occur during FastCGI
18//! communication and provides convenient type aliases for results.
19
20use crate::meta::{ProtocolStatus, RequestType};
21
22/// Result type alias for FastCGI client operations.
23pub type ClientResult<T> = Result<T, ClientError>;
24
25/// Result type alias for HTTP/FastCGI conversion operations.
26#[cfg(feature = "http")]
27pub type HttpConversionResult<T> = Result<T, HttpConversionError>;
28
29/// Error types that can occur during FastCGI communication.
30#[derive(Debug, thiserror::Error)]
31pub enum ClientError {
32 /// Wrapper of `std::io::Error`
33 #[error(transparent)]
34 Io(#[from] std::io::Error),
35
36 /// Usually not happen.
37 #[error("Response not found of request id `{id}`")]
38 RequestIdNotFound {
39 /// The request ID that was not found
40 id: u16,
41 },
42
43 /// Usually not happen.
44 #[error("Response not found of request id `{id}`")]
45 ResponseNotFound {
46 /// The request ID for which no response was found
47 id: u16,
48 },
49
50 /// Maybe unimplemented request type received fom response.
51 #[error("Response not found of request id `{request_type}`")]
52 UnknownRequestType {
53 /// The unknown request type received
54 request_type: RequestType,
55 },
56
57 /// Response not complete, first is protocol status and second is app
58 /// status, see fastcgi protocol.
59 #[error("This app can't multiplex [CantMpxConn]; AppStatus: {app_status}")]
60 EndRequestCantMpxConn {
61 /// The application status code
62 app_status: u32,
63 },
64
65 /// Response not complete, first is protocol status and second is app
66 /// status, see fastcgi protocol.
67 #[error("New request rejected; too busy [OVERLOADED]; AppStatus: {app_status}")]
68 EndRequestOverloaded {
69 /// The application status code
70 app_status: u32,
71 },
72
73 /// Response not complete, first is protocol status and second is app
74 /// status, see fastcgi protocol.
75 #[error("Role value not known [UnknownRole]; AppStatus: {app_status}")]
76 EndRequestUnknownRole {
77 /// The application status code
78 app_status: u32,
79 },
80}
81
82/// Error types that can occur while converting between FastCGI and HTTP types.
83#[cfg(feature = "http")]
84#[derive(Debug, thiserror::Error)]
85pub enum HttpConversionError {
86 /// Required FastCGI param is missing during HTTP conversion.
87 #[error("Missing FastCGI param `{name}`")]
88 MissingFastcgiParam {
89 /// The missing FastCGI param name.
90 name: &'static str,
91 },
92
93 /// Invalid HTTP method during conversion.
94 #[error(transparent)]
95 InvalidHttpMethod(#[from] ::http::method::InvalidMethod),
96
97 /// Invalid HTTP URI during conversion.
98 #[error(transparent)]
99 InvalidHttpUri(#[from] ::http::uri::InvalidUri),
100
101 /// Invalid HTTP header name during conversion.
102 #[error(transparent)]
103 InvalidHttpHeaderName(#[from] ::http::header::InvalidHeaderName),
104
105 /// Invalid HTTP header value during conversion.
106 #[error(transparent)]
107 InvalidHttpHeaderValue(#[from] ::http::header::InvalidHeaderValue),
108
109 /// Invalid HTTP status code during conversion.
110 #[error(transparent)]
111 InvalidHttpStatusCode(#[from] ::http::status::InvalidStatusCode),
112
113 /// Invalid HTTP message constructed by builder.
114 #[error(transparent)]
115 InvalidHttpMessage(#[from] ::http::Error),
116
117 /// CGI response payload could not be parsed into headers and body.
118 #[error("Malformed CGI response: {message}")]
119 MalformedHttpResponse {
120 /// Human-readable parse failure reason.
121 message: &'static str,
122 },
123}
124
125impl ClientError {
126 /// Creates a new end request error based on the protocol status.
127 ///
128 /// # Arguments
129 ///
130 /// * `protocol_status` - The protocol status returned by the FastCGI server
131 /// * `app_status` - The application status code
132 pub(crate) fn new_end_request_with_protocol_status(
133 protocol_status: ProtocolStatus, app_status: u32,
134 ) -> Self {
135 match protocol_status {
136 ProtocolStatus::CantMpxConn => ClientError::EndRequestCantMpxConn { app_status },
137 ProtocolStatus::Overloaded => ClientError::EndRequestOverloaded { app_status },
138 _ => ClientError::EndRequestUnknownRole { app_status },
139 }
140 }
141}