@@ -3,17 +3,17 @@ mod routes;
33mod utils;
44
55use crate :: {
6- db:: db :: DbClient ,
6+ db:: DbClient ,
77 routes:: { login:: login, register:: register} ,
88 utils:: structs:: ApiResponse ,
99} ;
1010use dotenvy:: dotenv;
1111use xitca_web:: {
1212 App , WebContext ,
1313 error:: Error ,
14- handler:: handler_service,
15- http:: { Response , StatusCode , WebResponse } ,
16- middleware:: { compress:: Compress , decompress :: Decompress , rate_limit:: RateLimit } ,
14+ handler:: { Responder , handler_service, json :: Json } ,
15+ http:: WebResponse ,
16+ middleware:: { compress:: Compress , rate_limit:: RateLimit } ,
1717 route:: post,
1818 service:: Service ,
1919} ;
@@ -25,59 +25,30 @@ pub struct AppState {
2525}
2626
2727/// Global error handler middleware.
28- /// Converts all errors to appropriate HTTP responses with correct status codes.
29- async fn error_handler < S , C , B > (
30- service : & S ,
31- mut ctx : WebContext < ' _ , C , B > ,
32- ) -> Result < WebResponse , Error >
28+ async fn error_handler < S , C > ( service : & S , mut ctx : WebContext < ' _ , C > ) -> Result < WebResponse , Error >
3329where
3430 C : ' static ,
35- B : ' static ,
36- S : for < ' r > Service < WebContext < ' r , C , B > , Response = WebResponse , Error = Error > ,
31+ S : for < ' r > Service < WebContext < ' r , C > , Response = WebResponse , Error = Error > ,
3732{
3833 match service. call ( ctx. reborrow ( ) ) . await {
3934 Ok ( res) => Ok ( res) ,
4035 Err ( e) => {
41- let error_msg = e. to_string ( ) ;
36+ // print and convert error to http response
37+ eprintln ! ( "{e}" ) ;
4238
43- // Map error types to appropriate HTTP status codes.
44- let status = if error_msg. contains ( "InvalidInput" ) || error_msg. contains ( "Validation" ) {
45- StatusCode :: BAD_REQUEST
46- } else if error_msg. contains ( "NotFound" ) {
47- StatusCode :: NOT_FOUND
48- } else if error_msg. contains ( "PermissionDenied" )
49- || error_msg. contains ( "Invalid email or password" )
50- {
51- StatusCode :: UNAUTHORIZED
52- } else if error_msg. contains ( "AlreadyExists" )
53- || error_msg. contains ( "already registered" )
54- {
55- StatusCode :: CONFLICT
56- } else {
57- StatusCode :: INTERNAL_SERVER_ERROR
58- } ;
39+ let res = e. call ( ctx. reborrow ( ) ) . await ?;
5940
60- // If error message is already JSON, use it directly.
61- // Otherwise, wrap in ApiResponse structure.
62- let json_body = if error_msg. starts_with ( '{' ) && error_msg. ends_with ( '}' ) {
63- error_msg
64- } else {
65- let error_response = ApiResponse :: < ( ) > {
41+ // override response body to json object.
42+ (
43+ res,
44+ Json ( ApiResponse :: < ( ) > {
6645 success : false ,
67- message : error_msg ,
46+ message : e . to_string ( ) ,
6847 data : None ,
69- } ;
70- serde_json:: to_string ( & error_response) . unwrap_or_else ( |_| {
71- r#"{"success":false,"message":"Internal error"}"# . to_string ( )
72- } )
73- } ;
74-
75- Ok ( Response :: builder ( )
76- . status ( status)
77- . header ( "content-type" , "application/json" )
78- . body ( json_body. into ( ) )
79- . unwrap ( )
80- . into ( ) )
48+ } ) ,
49+ )
50+ . respond ( ctx)
51+ . await
8152 }
8253 }
8354}
@@ -91,9 +62,7 @@ async fn main() -> std::io::Result<()> {
9162 let database_url = std:: env:: var ( "DATABASE_URL" ) . expect ( "DATABASE_URL must be set" ) ;
9263
9364 // Initialize connection pool.
94- let db_client = DbClient :: new ( & database_url)
95- . await
96- . map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , e) ) ?;
65+ let db_client = DbClient :: new ( & database_url) . await . map_err ( std:: io:: Error :: other) ?;
9766
9867 println ! ( "✓ Server running on http://localhost:8080" ) ;
9968
@@ -107,7 +76,6 @@ async fn main() -> std::io::Result<()> {
10776 . enclosed_fn ( error_handler) // Global error handling
10877 . enclosed ( RateLimit :: per_minute ( 60 ) ) // Rate limiting: 60 requests/minute
10978 . enclosed ( Compress ) // Response compression
110- . enclosed ( Decompress ) // Request decompression
11179 . serve ( )
11280 . bind ( "localhost:8080" ) ?
11381 . run ( )
0 commit comments