diff --git a/src/lib.rs b/src/lib.rs index 82102e6..c9d3099 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3028,11 +3028,15 @@ where /// /// Server Error Response /// +/// See [Section 5.2](https://datatracker.ietf.org/doc/html/rfc6749#section-5.2) of RFC 6749. /// This trait exists separately from the `StandardErrorResponse` struct /// to support customization by clients, such as supporting interoperability with -/// non-standards-complaint OAuth2 providers +/// non-standards-complaint OAuth2 providers. /// -pub trait ErrorResponse: Debug + DeserializeOwned + Serialize {} +/// The [`Display`] trait implementation for types implementing [`ErrorResponse`] should be a +/// human-readable string suitable for printing (e.g., within a [`RequestTokenError`]). +/// +pub trait ErrorResponse: Debug + Display + DeserializeOwned + Serialize {} /// /// Error types enum. @@ -3114,7 +3118,7 @@ impl StandardErrorResponse { } } -impl ErrorResponse for StandardErrorResponse where T: ErrorResponseType + 'static {} +impl ErrorResponse for StandardErrorResponse where T: ErrorResponseType + Display + 'static {} impl Display for StandardErrorResponse where @@ -3129,8 +3133,9 @@ where } if let Some(error_uri) = self.error_uri() { - formatted.push_str(" / See "); + formatted.push_str(" (see "); formatted.push_str(error_uri); + formatted.push(')'); } write!(f, "{}", formatted) @@ -3150,7 +3155,7 @@ where /// Error response returned by authorization server. Contains the parsed `ErrorResponse` /// returned by the server. /// - #[error("Server returned error response")] + #[error("Server returned error response: {0}")] ServerResponse(T), /// /// An error occurred while sending the request or receiving the response (e.g., network diff --git a/src/tests.rs b/src/tests.rs index 706994e..274abac 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1011,7 +1011,10 @@ fn test_exchange_code_with_simple_json_error() { format!("{:?}", token_err) ); // Test Display trait for RequestTokenError - assert_eq!("Server returned error response", format!("{}", token_err)); + assert_eq!( + "Server returned error response: invalid_request: stuff happened", + token_err.to_string() + ); } #[test] @@ -1141,7 +1144,7 @@ fn test_exchange_code_with_invalid_token_type() { fn test_exchange_code_with_400_status_code() { let body = r#"{"error":"invalid_request","error_description":"Expired code."}"#; let client = new_client(); - let token = client + let token_err = client .exchange_code(AuthorizationCode::new("ccc".to_string())) .request(mock_http_client( vec![ @@ -1161,12 +1164,12 @@ fn test_exchange_code_with_400_status_code() { .collect(), body: body.to_string().into_bytes(), }, - )); - - assert!(token.is_err()); + )) + .err() + .unwrap(); - match token.err().unwrap() { - RequestTokenError::ServerResponse(error_response) => { + match token_err { + RequestTokenError::ServerResponse(ref error_response) => { assert_eq!( BasicErrorResponseType::InvalidRequest, *error_response.error() @@ -1179,6 +1182,11 @@ fn test_exchange_code_with_400_status_code() { } other => panic!("Unexpected error: {:?}", other), } + + assert_eq!( + "Server returned error response: invalid_request: Expired code.", + token_err.to_string(), + ); } #[test] @@ -1457,7 +1465,7 @@ fn test_extension_with_simple_json_error() { assert!(token.is_err()); let token_err = token.err().unwrap(); - match &token_err { + match token_err { RequestTokenError::ServerResponse(ref error_response) => { assert_eq!(ColorfulErrorResponseType::TooLight, *error_response.error()); assert_eq!( @@ -1494,7 +1502,10 @@ fn test_extension_with_simple_json_error() { format!("{:?}", token_err) ); // Test Display trait for RequestTokenError - assert_eq!("Server returned error response", format!("{}", token_err)); + assert_eq!( + "Server returned error response: too_light: stuff happened (see https://errors)", + token_err.to_string() + ); } mod custom_errors {