@@ -6,7 +6,7 @@ use crate::middleware::{BodyLimitLayer, LayerStack, MiddlewareLayer, DEFAULT_BOD
66use crate :: response:: IntoResponse ;
77use crate :: router:: { MethodRouter , Router } ;
88use crate :: server:: Server ;
9- use std:: collections:: { BTreeMap , HashMap } ;
9+ use std:: collections:: BTreeMap ;
1010use tracing_subscriber:: { layer:: SubscriberExt , util:: SubscriberInitExt , EnvFilter } ;
1111
1212/// Main application builder for RustAPI
@@ -331,7 +331,8 @@ impl RustApi {
331331
332332 fn mount_auto_routes_grouped ( mut self ) -> Self {
333333 let routes = crate :: auto_route:: collect_auto_routes ( ) ;
334- let mut by_path: HashMap < String , MethodRouter > = HashMap :: new ( ) ;
334+ // Use BTreeMap for deterministic route registration order
335+ let mut by_path: BTreeMap < String , MethodRouter > = BTreeMap :: new ( ) ;
335336
336337 for route in routes {
337338 let method_enum = match route. method {
@@ -710,8 +711,12 @@ impl RustApi {
710711 let openapi_path = format ! ( "{}/openapi.json" , path) ;
711712
712713 // Clone values for closures
713- let spec_json =
714- serde_json:: to_string_pretty ( & self . openapi_spec . to_json ( ) ) . unwrap_or_default ( ) ;
714+ let spec_value = self . openapi_spec . to_json ( ) ;
715+ let spec_json = serde_json:: to_string_pretty ( & spec_value) . unwrap_or_else ( |e| {
716+ // Safe fallback if JSON serialization fails (though unlikely for Value)
717+ tracing:: error!( "Failed to serialize OpenAPI spec: {}" , e) ;
718+ "{}" . to_string ( )
719+ } ) ;
715720 let openapi_url = openapi_path. clone ( ) ;
716721
717722 // Add OpenAPI JSON endpoint
@@ -722,7 +727,13 @@ impl RustApi {
722727 . status ( http:: StatusCode :: OK )
723728 . header ( http:: header:: CONTENT_TYPE , "application/json" )
724729 . body ( crate :: response:: Body :: from ( json) )
725- . unwrap ( )
730+ . unwrap_or_else ( |e| {
731+ tracing:: error!( "Failed to build response: {}" , e) ;
732+ http:: Response :: builder ( )
733+ . status ( http:: StatusCode :: INTERNAL_SERVER_ERROR )
734+ . body ( crate :: response:: Body :: from ( "Internal Server Error" ) )
735+ . unwrap ( )
736+ } )
726737 }
727738 } ;
728739
@@ -815,8 +826,11 @@ impl RustApi {
815826 let expected_auth = format ! ( "Basic {}" , encoded) ;
816827
817828 // Clone values for closures
818- let spec_json =
819- serde_json:: to_string_pretty ( & self . openapi_spec . to_json ( ) ) . unwrap_or_default ( ) ;
829+ let spec_value = self . openapi_spec . to_json ( ) ;
830+ let spec_json = serde_json:: to_string_pretty ( & spec_value) . unwrap_or_else ( |e| {
831+ tracing:: error!( "Failed to serialize OpenAPI spec: {}" , e) ;
832+ "{}" . to_string ( )
833+ } ) ;
820834 let openapi_url = openapi_path. clone ( ) ;
821835 let expected_auth_spec = expected_auth. clone ( ) ;
822836 let expected_auth_docs = expected_auth;
@@ -834,7 +848,13 @@ impl RustApi {
834848 . status ( http:: StatusCode :: OK )
835849 . header ( http:: header:: CONTENT_TYPE , "application/json" )
836850 . body ( crate :: response:: Body :: from ( json) )
837- . unwrap ( )
851+ . unwrap_or_else ( |e| {
852+ tracing:: error!( "Failed to build response: {}" , e) ;
853+ http:: Response :: builder ( )
854+ . status ( http:: StatusCode :: INTERNAL_SERVER_ERROR )
855+ . body ( crate :: response:: Body :: from ( "Internal Server Error" ) )
856+ . unwrap ( )
857+ } )
838858 } )
839859 as std:: pin:: Pin < Box < dyn std:: future:: Future < Output = crate :: Response > + Send > >
840860 } ) ;
0 commit comments