File tree Expand file tree Collapse file tree 4 files changed +60
-5
lines changed Expand file tree Collapse file tree 4 files changed +60
-5
lines changed Original file line number Diff line number Diff line change @@ -5,14 +5,18 @@ All notable changes to this project will be documented in this file.
55
66## [ 0.10.7] - 2025-10-24
77
8+ ### Tests
9+ - Added regression coverage for long classifier needles to exercise the
10+ heap-allocation fallback.
11+
812### Changed
9- - Precomputed lowercase Turnkey classifier needles with a stack-backed buffer
13+ - Added an owning ` From<AppError> ` conversion for ` ErrorResponse ` and updated the
14+ Axum adapter to use it, eliminating redundant clones when building HTTP error
15+ bodies.
16+ - Precomputed lowercase Turnkey classifier needles with a stack-backed buffer
1017 to remove repeated transformations while keeping the common zero-allocation
1118 path for short patterns.
1219
13- ### Tests
14- - Added regression coverage for long classifier needles to exercise the
15- heap-allocation fallback.
1620
1721## [ 0.10.6] - 2025-09-21
1822
Original file line number Diff line number Diff line change @@ -77,7 +77,7 @@ impl IntoResponse for AppError {
7777 #[ cfg( feature = "serde_json" ) ]
7878 {
7979 // Build the stable wire contract (includes `code`).
80- let body: ErrorResponse = ( & self ) . into ( ) ;
80+ let body: ErrorResponse = self . into ( ) ;
8181 return body. into_response ( ) ;
8282 }
8383
Original file line number Diff line number Diff line change @@ -13,6 +13,33 @@ impl Display for ErrorResponse {
1313 }
1414}
1515
16+ impl From < AppError > for ErrorResponse {
17+ fn from ( err : AppError ) -> Self {
18+ let AppError {
19+ kind,
20+ message,
21+ retry,
22+ www_authenticate
23+ } = err;
24+
25+ let status = kind. http_status ( ) ;
26+ let code = AppCode :: from ( kind) ;
27+ let message = match message {
28+ Some ( msg) => msg. into_owned ( ) ,
29+ None => String :: from ( "An error occurred" )
30+ } ;
31+
32+ Self {
33+ status,
34+ code,
35+ message,
36+ details : None ,
37+ retry,
38+ www_authenticate
39+ }
40+ }
41+ }
42+
1643impl From < & AppError > for ErrorResponse {
1744 fn from ( err : & AppError ) -> Self {
1845 let status = err. kind . http_status ( ) ;
Original file line number Diff line number Diff line change @@ -147,6 +147,30 @@ fn from_app_error_uses_default_message_when_none() {
147147 assert_eq ! ( e. message, "An error occurred" ) ;
148148}
149149
150+ #[ test]
151+ fn from_owned_app_error_moves_message_and_metadata ( ) {
152+ let err = AppError :: unauthorized ( String :: from ( "owned message" ) )
153+ . with_retry_after_secs ( 5 )
154+ . with_www_authenticate ( "Bearer" ) ;
155+
156+ let resp: ErrorResponse = err. into ( ) ;
157+
158+ assert_eq ! ( resp. status, 401 ) ;
159+ assert ! ( matches!( resp. code, AppCode :: Unauthorized ) ) ;
160+ assert_eq ! ( resp. message, "owned message" ) ;
161+ assert_eq ! ( resp. retry. unwrap( ) . after_seconds, 5 ) ;
162+ assert_eq ! ( resp. www_authenticate. as_deref( ) , Some ( "Bearer" ) ) ;
163+ }
164+
165+ #[ test]
166+ fn from_owned_app_error_defaults_message_when_absent ( ) {
167+ let resp: ErrorResponse = AppError :: bare ( AppErrorKind :: Internal ) . into ( ) ;
168+
169+ assert_eq ! ( resp. status, 500 ) ;
170+ assert ! ( matches!( resp. code, AppCode :: Internal ) ) ;
171+ assert_eq ! ( resp. message, "An error occurred" ) ;
172+ }
173+
150174// --- Display formatting --------------------------------------------------
151175
152176#[ test]
You can’t perform that action at this time.
0 commit comments