Description
Bad Requests
Describe the bug
When I made a create entity request with two required fields missing, I got the following error:
HTTP/1.1 400
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: close
Content-Type: application/json
Date: Wed, 20 Oct 2021 10:33:51 GMT
Expires: 0
Pragma: no-cache
Transfer-Encoding: chunked
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
{
"ets": 1634726031652,
"id": "open-saber.registry.invite",
"params": {
"err": "",
"errmsg": "Validation Exception : #/Teacher : #/Teacher: 2 schema violations found",
"msgid": "53cefdb9-288f-4cc5-9f9d-d108837afbee",
"resmsgid": "",
"status": "UNSUCCESSFUL"
},
"responseCode": "OK",
"ver": "1.0"
}
Expected behavior
Since the status code is 400
, responseCode
should be Bad Request
, not OK
. Also, it would be helpful to the client if the error explains why the error occurred and how it could be resolved. Here is an example of the error message a developer/client application would like to receive for a bad request:
HTTP/1.1 400
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: close
Content-Type: application/json
Date: Wed, 20 Oct 2021 10:33:51 GMT
Expires: 0
X-Server: http://rg:8081/
X-Request-Id: 53cefdb9-288f-4cc5-9f9d-d108837afbee
{
"error": {
"code": 400,
"status": "Bad Request"
"errors": [
{
"operation": "registry.invite",
"location": "request.body.email",
"message": "`email` is a mandatory field in the `Teacher` schema. Please provide the email in the request body alongside the other attributes and try the request again.",
"reason": "badRequest"
},
{
"operation": "registry.invite",
"location": "request.body.subject",
"message": "`subject` is an enum - it's value can only be one of 'Math', 'Hindi', 'English', 'History', 'Geography', 'Physics', 'Chemistry', 'Biology' in the `Teacher` schema. Please provide a valid subject in the request body alongside the other attributes and try the request again.",
"reason": "badRequest"
}
],
"message": "Two schema violations detected. Please make the requested changes and retry the request."
}
}
It would be more consistent if a similar error is returned when I make a request to send a claim for attestation, but make an error while sending the request body. Currently, I get the following error:
HTTP/1.1 404
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Type: application/json
Date: Wed, 20 Oct 2021 11:23:55 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
Set-Cookie: JSESSIONID=B817F10950DBB4AB426CD927EB14C1EF; Path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
{
"ets": 1634729035682,
"id": "open-saber.registry.update",
"params": {
"err": "",
"errmsg": "Validation Exception : #/Student/school : #/Student/school: expected type: String, found: JSONObject",
"msgid": "f973e0d6-7a76-4d8d-8616-d7b051373987",
"resmsgid": "",
"status": "UNSUCCESSFUL"
},
"responseCode": "OK",
"ver": "1.0"
}
Since the error is regarding a bad request, the returned HTTP status code should be 400
, not 404
. The responseCode
in the request body should be Bad Request
, not OK
. An example error message that would be great (similar to the one above):
HTTP/1.1 400
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: close
Content-Type: application/json
Date: Wed, 20 Oct 2021 10:33:51 GMT
Expires: 0
X-Server: http://rg:8081/
X-Request-Id: f973e0d6-7a76-4d8d-8616-d7b051373987
{
"error": {
"code": 400,
"status": "Bad Request"
"errors": [
{
"operation": "registry.update-claim",
"location": "request.body",
"message": "`school` is of type `String` in the `Teacher` schema. Please provide only the value for `school` in the request body as a JSON `String` (found `JSONObject` instead) and try the request again.",
"reason": "badRequest"
}
],
"message": "One schema violation detected. Please make the requested change and retry the request."
}
}
Forbidden Requests
Describe the bug
When I made a get entity request with the access token for another entity, I got the following error:
HTTP/1.1 403
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Date: Wed, 20 Oct 2021 10:49:13 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
Set-Cookie: JSESSIONID=937462B8331D4B7ABB4BA9DE8DCBF199; Path=/; HttpOnly
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Expected behavior
It would be helpful to the client if there was an error object returned that explains why the error occurred and how it could be resolved. Here is an example of the error message a client application/developer would like to receive for a forbidden request:
HTTP/1.1 403
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: close
Content-Type: application/json
Date: Wed, 20 Oct 2021 10:33:51 GMT
Expires: 0
X-Server: http://rg:8081/
X-Request-Id: 67ckfddn-288f-998s-00xk-d82s8FidSbee
{
"error": {
"code": 403,
"status": "Forbidden"
"errors": [
{
"operation": "registry.retrieve",
"location": "request.headers.authorization",
"message": "You do not have sufficient permissions to perform this operation.",
"reason": "forbidden"
}
],
"message": "You are not permitted to perform this operation."
}
}
The same error should be returned when no access token is provided. Currently, it returns a redirect to the keycloak login page:
HTTP/1.1 302
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Date: Wed, 20 Oct 2021 10:55:27 GMT
Expires: 0
Keep-Alive: timeout=60
Location: http://kc:8080/auth/realms/sunbird-rc/protocol/openid-connect/auth?response_type=code&client_id=registry-frontend&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fapi%2Fv1%2FStudent%2F1-cccea3dd-47af-494b-acf6-442f5bcf586c&state=0b032fae-39f3-4f7a-a761-9cddda52089b&login=true&scope=openid
Pragma: no-cache
Set-Cookie: OAuth_Token_Request_State=0b032fae-39f3-4f7a-a761-9cddda52089b; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Even if I follow the URL and authenticate as the user, it takes me to a whitelabel error page:
Since this is an API call (/api/v1/...
), it will most probably be a developer or their application making a request, and not a user in their browser. A developer/client application will want a 403
error as a response instead of a 200
code and an HTML login page from keycloak.
Expired/Invalid Token
Describe the bug
When I make a request with an expired access token, I get the following error:
HTTP/1.1 401
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Date: Wed, 20 Oct 2021 11:05:25 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
WWW-Authenticate: Bearer realm="sunbird-rc", error="invalid_token", error_description="Token is not active", Bearer realm="sunbird-rc", error="invalid_token", error_description="Token is not active"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Expected behavior
It is not a good practice to return errors in headers. cURL
does not even show response headers or a status code by default - a developer would be puzzled as to what happened if they didn't use certain flags to show the response headers in cURL
. Here is an example of the error message an API client/developer would like to receive for a request with invalid/expired credentials:
HTTP/1.1 401
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: close
Content-Type: application/json
Date: Wed, 20 Oct 2021 10:33:51 GMT
Expires: 0
X-Server: http://rg:8081/
X-Request-Id: 8x8ksaw0c-7hk2-1lxu-cls5-83ld8Fi7glwb
{
"error": {
"code": 403,
"status": "Forbidden"
"errors": [
{
"operation": "registry.retrieve",
"location": "request.headers.authorization",
"message": "Your access token is invalid or expired. Please get a new access token and retry this request with it.",
"reason": "invalidCredentials"
}
],
"message": "Your access token is invalid or expired."
}
}