@@ -15,6 +15,7 @@ use crate::{
15
15
use axum_core:: { extract:: Request , response:: IntoResponse , BoxError } ;
16
16
use bytes:: BytesMut ;
17
17
use std:: {
18
+ borrow:: Cow ,
18
19
convert:: Infallible ,
19
20
fmt,
20
21
task:: { Context , Poll } ,
@@ -1031,58 +1032,66 @@ where
1031
1032
self
1032
1033
}
1033
1034
1034
- #[ track_caller]
1035
- pub ( crate ) fn merge_for_path ( mut self , path : Option < & str > , other : MethodRouter < S , E > ) -> Self {
1035
+ pub ( crate ) fn merge_for_path (
1036
+ mut self ,
1037
+ path : Option < & str > ,
1038
+ other : MethodRouter < S , E > ,
1039
+ ) -> Result < Self , Cow < ' static , str > > {
1036
1040
// written using inner functions to generate less IR
1037
- #[ track_caller]
1038
1041
fn merge_inner < S , E > (
1039
1042
path : Option < & str > ,
1040
1043
name : & str ,
1041
1044
first : MethodEndpoint < S , E > ,
1042
1045
second : MethodEndpoint < S , E > ,
1043
- ) -> MethodEndpoint < S , E > {
1046
+ ) -> Result < MethodEndpoint < S , E > , Cow < ' static , str > > {
1044
1047
match ( first, second) {
1045
- ( MethodEndpoint :: None , MethodEndpoint :: None ) => MethodEndpoint :: None ,
1046
- ( pick, MethodEndpoint :: None ) | ( MethodEndpoint :: None , pick) => pick,
1048
+ ( MethodEndpoint :: None , MethodEndpoint :: None ) => Ok ( MethodEndpoint :: None ) ,
1049
+ ( pick, MethodEndpoint :: None ) | ( MethodEndpoint :: None , pick) => Ok ( pick) ,
1047
1050
_ => {
1048
1051
if let Some ( path) = path {
1049
- panic ! (
1052
+ Err ( format ! (
1050
1053
"Overlapping method route. Handler for `{name} {path}` already exists"
1051
- ) ;
1054
+ )
1055
+ . into ( ) )
1052
1056
} else {
1053
- panic ! (
1057
+ Err ( format ! (
1054
1058
"Overlapping method route. Cannot merge two method routes that both \
1055
1059
define `{name}`"
1056
- ) ;
1060
+ )
1061
+ . into ( ) )
1057
1062
}
1058
1063
}
1059
1064
}
1060
1065
}
1061
1066
1062
- self . get = merge_inner ( path, "GET" , self . get , other. get ) ;
1063
- self . head = merge_inner ( path, "HEAD" , self . head , other. head ) ;
1064
- self . delete = merge_inner ( path, "DELETE" , self . delete , other. delete ) ;
1065
- self . options = merge_inner ( path, "OPTIONS" , self . options , other. options ) ;
1066
- self . patch = merge_inner ( path, "PATCH" , self . patch , other. patch ) ;
1067
- self . post = merge_inner ( path, "POST" , self . post , other. post ) ;
1068
- self . put = merge_inner ( path, "PUT" , self . put , other. put ) ;
1069
- self . trace = merge_inner ( path, "TRACE" , self . trace , other. trace ) ;
1070
- self . connect = merge_inner ( path, "CONNECT" , self . connect , other. connect ) ;
1067
+ self . get = merge_inner ( path, "GET" , self . get , other. get ) ? ;
1068
+ self . head = merge_inner ( path, "HEAD" , self . head , other. head ) ? ;
1069
+ self . delete = merge_inner ( path, "DELETE" , self . delete , other. delete ) ? ;
1070
+ self . options = merge_inner ( path, "OPTIONS" , self . options , other. options ) ? ;
1071
+ self . patch = merge_inner ( path, "PATCH" , self . patch , other. patch ) ? ;
1072
+ self . post = merge_inner ( path, "POST" , self . post , other. post ) ? ;
1073
+ self . put = merge_inner ( path, "PUT" , self . put , other. put ) ? ;
1074
+ self . trace = merge_inner ( path, "TRACE" , self . trace , other. trace ) ? ;
1075
+ self . connect = merge_inner ( path, "CONNECT" , self . connect , other. connect ) ? ;
1071
1076
1072
1077
self . fallback = self
1073
1078
. fallback
1074
1079
. merge ( other. fallback )
1075
- . expect ( "Cannot merge two `MethodRouter`s that both have a fallback" ) ;
1080
+ . ok_or ( "Cannot merge two `MethodRouter`s that both have a fallback" ) ? ;
1076
1081
1077
1082
self . allow_header = self . allow_header . merge ( other. allow_header ) ;
1078
1083
1079
- self
1084
+ Ok ( self )
1080
1085
}
1081
1086
1082
1087
#[ doc = include_str ! ( "../docs/method_routing/merge.md" ) ]
1083
1088
#[ track_caller]
1084
1089
pub fn merge ( self , other : MethodRouter < S , E > ) -> Self {
1085
- self . merge_for_path ( None , other)
1090
+ match self . merge_for_path ( None , other) {
1091
+ Ok ( t) => t,
1092
+ // not using unwrap or unwrap_or_else to get a clean panic message + the right location
1093
+ Err ( e) => panic ! ( "{e}" ) ,
1094
+ }
1086
1095
}
1087
1096
1088
1097
/// Apply a [`HandleErrorLayer`].
0 commit comments