@@ -18,8 +18,17 @@ const RUSTDOC_CSS: &str = include_str!(concat!(env!("OUT_DIR"), "/rustdoc.css"))
18
18
const RUSTDOC_2021_12_05_CSS : & str =
19
19
include_str ! ( concat!( env!( "OUT_DIR" ) , "/rustdoc-2021-12-05.css" ) ) ;
20
20
21
+ /// handle io-errors while serving static files.
22
+ ///
23
+ /// Some errors can directly converted into a `404 NOT FOUND`,
24
+ /// the rest will lead to a server error.
21
25
async fn handle_error ( err : io:: Error ) -> impl IntoResponse {
22
- AxumNope :: InternalError ( err. into ( ) ) . into_response ( )
26
+ match err. raw_os_error ( ) {
27
+ // ENOTDIR -> "not a directory
28
+ Some ( 20 ) => AxumNope :: ResourceNotFound ,
29
+ // fallback: raise a server error
30
+ _ => AxumNope :: InternalError ( err. into ( ) ) ,
31
+ }
23
32
}
24
33
25
34
fn build_static_css_response ( content : & ' static str ) -> impl IntoResponse {
@@ -133,6 +142,24 @@ mod tests {
133
142
} ) ;
134
143
}
135
144
145
+ #[ test]
146
+ fn io_error_not_a_directory_leads_to_404 ( ) {
147
+ wrapper ( |env| {
148
+ let web = env. frontend ( ) ;
149
+
150
+ // just to be sure that `index.js` exists
151
+ assert ! ( web. get( "/-/static/index.js" ) . send( ) ?. status( ) . is_success( ) ) ;
152
+
153
+ // `index.js` exists, but is not a directory,
154
+ // so trying to fetch it via `ServeDir` will lead
155
+ // to an IO-error.
156
+ let resp = web. get ( "/-/static/index.js/something" ) . send ( ) ?;
157
+ assert_eq ! ( resp. status( ) . as_u16( ) , StatusCode :: NOT_FOUND ) ;
158
+
159
+ Ok ( ( ) )
160
+ } ) ;
161
+ }
162
+
136
163
#[ test_case( "/-/static/index.js" , "copyTextHandler" ) ]
137
164
#[ test_case( "/-/static/menu.js" , "closeMenu" ) ]
138
165
#[ test_case( "/-/static/keyboard.js" , "handleKey" ) ]
0 commit comments