11//! Contains and additional impl for TmcCore for calling the TMC Server API.
22
33use crate :: error:: CoreError ;
4- use crate :: response:: Response ;
4+ use crate :: response:: ErrorResponse ;
55use crate :: {
66 Course , CourseData , CourseDataExercise , CourseDataExercisePoint , CourseDetails , CourseExercise ,
77 ExerciseDetails , FeedbackAnswer , NewSubmission , Organization , Review , Submission ,
@@ -23,54 +23,28 @@ use url::Url;
2323/// Provides a wrapper for reqwest Response's json that deserializes into Response<T> and converts it into a result
2424trait CoreExt {
2525 fn json_res < T : DeserializeOwned > ( self ) -> Result < T , CoreError > ;
26- fn check_error ( self , url : Url ) -> Result < Self , CoreError >
27- where
28- Self : Sized ;
2926}
3027
3128impl CoreExt for ReqwestResponse {
32- #[ cfg( not( test) ) ]
3329 fn json_res < T : DeserializeOwned > ( self ) -> Result < T , CoreError > {
34- let res: Response < T > = self . json ( ) . map_err ( CoreError :: HttpJsonResponse ) ?;
35- res. into_result ( )
36- }
37-
38- // logs received JSON for easier debugging in tests
39- #[ cfg( test) ]
40- fn json_res < T : DeserializeOwned > ( self ) -> Result < T , CoreError > {
41- let res: Value = self . json ( ) . map_err ( CoreError :: HttpJsonResponse ) ?;
42- log:: debug!( "JSON {}" , res) ;
43- let res: Response < T > = serde_json:: from_value ( res) . unwrap ( ) ;
44- res. into_result ( )
45- }
46-
47- fn check_error ( self , url : Url ) -> Result < Self , CoreError > {
30+ let url = self . url ( ) . clone ( ) ;
4831 let status = self . status ( ) ;
4932 if status. is_success ( ) {
50- Ok ( self )
33+ Ok ( self . json ( ) . map_err ( CoreError :: HttpJsonResponse ) ? )
5134 } else {
52- let text = self . text ( ) . unwrap_or_default ( ) ;
53- // todo: clean the parsing
54- let parsed = serde_json:: from_str :: < Value > ( & text)
55- . ok ( )
56- . and_then ( |ok| {
57- ok. as_object ( ) . and_then ( |obj|
58- // parses either the error string or errors string array
59- if let Some ( error) = obj. get ( "error" ) . and_then ( |e| e. as_str ( ) ) {
60- Some ( error. to_string ( ) )
61- } else if let Some ( errors) = obj. get ( "errors" ) . and_then ( |e| e. as_array ( ) ) {
62- let errors = errors
63- . iter ( )
64- . filter_map ( |e| e. as_str ( ) )
65- . collect :: < Vec < _ > > ( )
66- . join ( ". " ) ;
67- Some ( errors)
68- } else {
69- None
70- } )
71- } )
72- . unwrap_or ( text) ;
73- Err ( CoreError :: HttpError ( url, status, parsed) )
35+ let err: ErrorResponse = self . json ( ) . map_err ( CoreError :: HttpJsonResponse ) ?;
36+ let error = match ( err. error , err. errors ) {
37+ ( Some ( err) , Some ( errs) ) => format ! ( "{}, {}" , err, errs. join( "," ) ) ,
38+ ( Some ( err) , None ) => err,
39+ ( None , Some ( errs) ) => errs. join ( "," ) ,
40+ _ => "" . to_string ( ) ,
41+ } ;
42+ Err ( CoreError :: HttpError {
43+ url,
44+ status,
45+ error,
46+ obsolete_client : err. obsolete_client ,
47+ } )
7448 }
7549 }
7650}
@@ -111,8 +85,7 @@ impl TmcCore {
11185 . get ( url. clone ( ) )
11286 . core_headers ( self )
11387 . send ( )
114- . map_err ( |e| CoreError :: ConnectionError ( Method :: GET , url. clone ( ) , e) ) ?
115- . check_error ( url) ?
88+ . map_err ( |e| CoreError :: ConnectionError ( Method :: GET , url, e) ) ?
11689 . json_res ( )
11790 }
11891
@@ -129,8 +102,7 @@ impl TmcCore {
129102 . get ( url. clone ( ) )
130103 . core_headers ( self )
131104 . send ( )
132- . map_err ( |e| CoreError :: ConnectionError ( Method :: GET , url. clone ( ) , e) ) ?
133- . check_error ( url) ?
105+ . map_err ( |e| CoreError :: ConnectionError ( Method :: GET , url, e) ) ?
134106 . copy_to ( & mut target_file)
135107 . map_err ( |e| CoreError :: HttpWriteResponse ( target. to_path_buf ( ) , e) ) ?;
136108 Ok ( ( ) )
@@ -144,8 +116,7 @@ impl TmcCore {
144116 . get ( url. clone ( ) )
145117 . core_headers ( self )
146118 . send ( )
147- . map_err ( |e| CoreError :: ConnectionError ( Method :: GET , url. clone ( ) , e) ) ?
148- . check_error ( url) ?
119+ . map_err ( |e| CoreError :: ConnectionError ( Method :: GET , url, e) ) ?
149120 . copy_to ( & mut target_file)
150121 . map_err ( |e| CoreError :: HttpWriteResponse ( target. to_path_buf ( ) , e) ) ?;
151122 Ok ( ( ) )
@@ -709,8 +680,7 @@ impl TmcCore {
709680 . multipart ( form)
710681 . core_headers ( self )
711682 . send ( )
712- . map_err ( |e| CoreError :: ConnectionError ( Method :: POST , submission_url. clone ( ) , e) ) ?
713- . check_error ( submission_url) ?
683+ . map_err ( |e| CoreError :: ConnectionError ( Method :: POST , submission_url, e) ) ?
714684 . json_res ( ) ?;
715685 log:: debug!( "received {:?}" , res) ;
716686 Ok ( res)
@@ -762,8 +732,7 @@ impl TmcCore {
762732 . multipart ( form)
763733 . core_headers ( self )
764734 . send ( )
765- . map_err ( |e| CoreError :: ConnectionError ( Method :: POST , feedback_url. clone ( ) , e) ) ?
766- . check_error ( feedback_url) ?
735+ . map_err ( |e| CoreError :: ConnectionError ( Method :: POST , feedback_url, e) ) ?
767736 . json_res ( )
768737 }
769738
@@ -788,8 +757,7 @@ impl TmcCore {
788757 . query ( & [ ( "review[points]" , review_points) ] )
789758 . core_headers ( self )
790759 . send ( )
791- . map_err ( |e| CoreError :: ConnectionError ( Method :: POST , url. clone ( ) , e) ) ?
792- . check_error ( url) ?
760+ . map_err ( |e| CoreError :: ConnectionError ( Method :: POST , url, e) ) ?
793761 . json_res ( ) ?;
794762 log:: trace!( "received {:?}" , res) ;
795763 Ok ( ( ) )
@@ -815,8 +783,7 @@ impl TmcCore {
815783 . post ( url. clone ( ) )
816784 . multipart ( form)
817785 . send ( )
818- . map_err ( |e| CoreError :: ConnectionError ( Method :: POST , url. clone ( ) , e) ) ?
819- . check_error ( url) ?
786+ . map_err ( |e| CoreError :: ConnectionError ( Method :: POST , url, e) ) ?
820787 . json_res ( )
821788 }
822789}
0 commit comments