Skip to content

Commit

Permalink
Merge pull request #429 from jikan-me/enhancement/exceptions
Browse files Browse the repository at this point in the history
Exception Handling enhancement
  • Loading branch information
irfan-dahir authored Jul 22, 2023
2 parents cc0267f + 6a0204b commit d01ed99
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 48 deletions.
40 changes: 22 additions & 18 deletions app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public function render($request, \Throwable $e): JsonResponse|Response
->json([
'status' => 500,
'type' => 'ConnectionException',
'message' => 'Failed to communicate with Redis.',
'message' => 'Failed to communicate with the Redis server',
'error' => env('APP_DEBUG') ? $e->getMessage() : null,
'report_url' => env('GITHUB_REPORTING', true) ? (string) $githubReport : null
], 500);
Expand Down Expand Up @@ -137,8 +137,8 @@ public function render($request, \Throwable $e): JsonResponse|Response
return response()
->json([
'status' => $e->getCode(),
'type' => 'BadResponseException',
'message' => 'Jikan is being rate limited by MyAnimeList',
'type' => 'RateLimitException',
'message' => 'Jikan is being rate limited by MyAnimeList.',
'error' => $e->getMessage()
], $e->getCode());
case 403:
Expand All @@ -152,38 +152,42 @@ public function render($request, \Throwable $e): JsonResponse|Response

return response()
->json([
'status' => $e->getCode(),
'type' => 'BadResponseException',
'message' => 'Jikan failed to connect to MyAnimeList.net. MyAnimeList.net may be down/unavailable, refuses to connect or took too long to respond.',
'status' => 500,
'type' => 'UpstreamException',
'message' => 'Request to MyAnimeList.net failed. MyAnimeList.net may be down/unavailable, refuses to connect or took too long to respond. Please try again later.',
'error' => $e->getMessage()
], 503);
], 500);
default:
return response()
->json([
'status' => $e->getCode(),
'type' => 'BadResponseException',
'message' => 'Something went wrong, please try again later',
'message' => 'Something went wrong, please try again later.',
'error' => $e->getMessage()
], $e->getCode());
}
}

if ($e instanceof TimeoutException) {
event(new SourceHeartbeatEvent(SourceHeartbeatEvent::BAD_HEALTH, $e->getCode()));

return response()
->json([
'status' => 408,
'type' => 'TimeoutException',
'message' => 'Request to MyAnimeList.net timed out (' .env('SOURCE_TIMEOUT', 5) . ' seconds)',
'status' => 500,
'type' => 'UpstreamException',
'message' => 'Request to MyAnimeList.net timed out (' .env('SOURCE_TIMEOUT', 5) . ' seconds). Please try again later.',
'error' => $e->getMessage()
], 408);
], 500);
}

if ($e instanceof TransportException) {
event(new SourceHeartbeatEvent(SourceHeartbeatEvent::BAD_HEALTH, $e->getCode()));

return response()
->json([
'status' => 500,
'type' => 'TransportException',
'message' => 'Request to MyAnimeList.net has failed. The upstream server has returned a non-successful status code.',
'type' => 'UpstreamException',
'message' => 'Request to MyAnimeList.net failed. MyAnimeList.net may be down/unavailable, refuses to connect or took too long to respond. Please try again later.',
'error' => $e->getMessage()
], 500);
}
Expand All @@ -193,11 +197,11 @@ public function render($request, \Throwable $e): JsonResponse|Response

return response()
->json([
'status' => $e->getCode(),
'type' => 'BadResponseException',
'message' => 'Jikan failed to connect to MyAnimeList.net. MyAnimeList.net may be down/unavailable, refuses to connect or took too long to respond. Retry the request!',
'status' => 500,
'type' => 'UpstreamException',
'message' => 'Request to MyAnimeList.net failed. MyAnimeList.net may be down/unavailable, refuses to connect or took too long to respond. Please try again later.',
'error' => $e->getMessage()
], 503);
], 500);
}

// Bad REST API requests
Expand Down
51 changes: 24 additions & 27 deletions config/swagger-lume.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@
'API_DESCRIPTION' => str_replace("\r\n", "\n", <<<EOF
[Jikan](https://jikan.moe) is an **Unofficial** MyAnimeList API.
It scrapes the website to satisfy the need for a complete API - which MyAnimeList lacks.
# Information
⚡ Jikan is powered by it's awesome backers - 🙏 [Become a backer](https://www.patreon.com/jikan)
Expand All @@ -212,10 +212,12 @@
| Duration | Requests |
|----|----|
| Monthly | **Unlimited** |
| Daily | **Unlimited** |
| Per Minute | 60 requests |
| Per Second | 3 requests |
Note: It's still possible to get rate limited from MyAnimeList.net instead.
## JSON Notes
- Any property (except arrays or objects) whose value does not exist or is undetermined, will be `null`.
Expand All @@ -226,23 +228,18 @@
## Caching
By **CACHING**, we refer to the data parsed from MyAnimeList which is stored temporarily on our servers to provide better API performance.
All requests, by default are cached for **24 hours** except the following endpoints which have their own unique cache **Time To Live**.
| Request | TTL |
| ---- | ---- |
| All (Default) | 24 hours |
All requests are cached for **24 hours**.
The following response headers will detail cache information.
| Header | Remarks |
| ---- | ---- |
| `Expires` | Cache expiry date |
| `Last-Modified` | Cache set date |
| `X-Request-Fingerprint` | Unique request fingerprint |
| `X-Request-Fingerprint` | Unique request fingerprint (only for cachable requests, not queries) |
Note: Caching headers will only be available on single resource requests and their child endpoints. e.g `/anime/1`, `/anime/1/relations`.
Note: `X-Request-Fingerprint` will only be available on single resource requests and their child endpoints. e.g `/anime/1`, `/anime/1/relations`.
They won't be available on pages which perform queries, like /anime, or /top/anime, etc.
## Allowed HTTP(s) requests
Expand All @@ -252,26 +249,26 @@
## HTTP Responses
| HTTP Status | Remarks |
| ---- | ---- |
| `200 - OK` | The request was successful |
| `304 - Not Modified` | You have the latest data (Cache Validation response) |
| `400 - Bad Request` | You've made an invalid request. Recheck documentation |
| `404 - Not Found` | The resource was not found or MyAnimeList responded with a `404` |
| `405 - Method Not Allowed` | Requested Method is not supported for resource. Only `GET` requests are allowed |
| `429 - Too Many Request` | You are being rate limited by Jikan or MyAnimeList is rate-limiting our servers (specified in the error response) |
| `500 - Internal Server Error` | Something is not working on our end. If you see an error response with a `report_url` URL, please click on it to open an auto-generated GitHub issue |
| `503 - Service Unavailable` | The service has broke. |
All error responses are accompanied by a JSON Error response.
| Exception | HTTP Status | Remarks |
| ---- | ---- | ---- |
| N/A | `200 - OK` | The request was successful |
| N/A | `304 - Not Modified` | You have the latest data (Cache Validation response) |
| `BadRequestException|ValidationException` | `400 - Bad Request` | You've made an invalid request. Recheck documentation |
| `BadResponseException` | `404 - Not Found` | The resource was not found or MyAnimeList responded with a `404` |
| `BadRequestException` | `405 - Method Not Allowed` | Requested Method is not supported for resource. Only `GET` requests are allowed |
| `RateLimitException` | `429 - Too Many Request` | You are being rate limited by Jikan or MyAnimeList is rate-limiting our servers (specified in the error response) |
| `UpstreamException|ParserException`, Multiple | `500 - Internal Server Error` | Something didn't work. Try again later. If you see an error response with a `report_url` URL, please click on it to open an auto-generated GitHub issue |
## JSON Error Response
```json
{
"status": 404,
"type": "BadResponseException",
"message": "Resource does not exist",
"error": "Something Happened",
"status": 500,
"type": "InternalException",
"message": "Exception Message",
"error": "Exception Trace",
"report_url": "https://github.com..."
}
```
Expand All @@ -282,7 +279,7 @@
| `type` | Thrown Exception |
| `message` | Human-readable error message |
| `error` | Error response and trace from the API |
| `report_url` | Clicking this would redirect you to a generated GitHub issue. ℹ It's only returned on a parser error. |
| `report_url` | Clicking this would redirect you to a generated GitHub issue |
## Cache Validation
Expand Down
4 changes: 1 addition & 3 deletions storage/api-docs/api-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"openapi": "3.0.0",
"info": {
"title": "Jikan API",
"description": "[Jikan](https://jikan.moe) is an **Unofficial** MyAnimeList API.\nIt scrapes the website to satisfy the need for a complete API - which MyAnimeList lacks.\n\n# Information\n\n⚡ Jikan is powered by it's awesome backers - 🙏 [Become a backer](https://www.patreon.com/jikan)\n\n## Rate Limiting\n\n| Duration | Requests |\n|----|----|\n| Monthly | **Unlimited** |\n| Per Minute | 60 requests |\n| Per Second | 3 requests |\n\n\n## JSON Notes\n- Any property (except arrays or objects) whose value does not exist or is undetermined, will be `null`.\n- Any array or object property whose value does not exist or is undetermined, will be empty.\n- Any `score` property whose value does not exist or is undetermined, will be `0`.\n- All dates and timestamps are returned in [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) format and in UTC timezone\n\n## Caching\nBy **CACHING**, we refer to the data parsed from MyAnimeList which is stored temporarily on our servers to provide better API performance.\n\nAll requests, by default are cached for **24 hours** except the following endpoints which have their own unique cache **Time To Live**. \n\n| Request | TTL |\n| ---- | ---- |\n| All (Default) | 24 hours |\n\n\nThe following response headers will detail cache information.\n\n| Header | Remarks |\n| ---- | ---- |\n| `Expires` | Cache expiry date |\n| `Last-Modified` | Cache set date |\n| `X-Request-Fingerprint` | Unique request fingerprint |\n\n\nNote: Caching headers will only be available on single resource requests and their child endpoints. e.g `/anime/1`, `/anime/1/relations`. \nThey won't be available on pages which perform queries, like /anime, or /top/anime, etc.\n\n## Allowed HTTP(s) requests\n\n**Jikan REST API does not provide authenticated requests for MyAnimeList.** This means you can not use it to update your anime/manga list.\nOnly GET requests are supported which return READ-ONLY data.\n\n## HTTP Responses\n\n| HTTP Status | Remarks |\n| ---- | ---- |\n| `200 - OK` | The request was successful |\n| `304 - Not Modified` | You have the latest data (Cache Validation response) |\n| `400 - Bad Request` | You've made an invalid request. Recheck documentation |\n| `404 - Not Found` | The resource was not found or MyAnimeList responded with a `404` |\n| `405 - Method Not Allowed` | Requested Method is not supported for resource. Only `GET` requests are allowed |\n| `429 - Too Many Request` | You are being rate limited by Jikan or MyAnimeList is rate-limiting our servers (specified in the error response) |\n| `500 - Internal Server Error` | Something is not working on our end. If you see an error response with a `report_url` URL, please click on it to open an auto-generated GitHub issue |\n| `503 - Service Unavailable` | The service has broke. |\n\n\n## JSON Error Response\n\n```json\n {\n \"status\": 404,\n \"type\": \"BadResponseException\",\n \"message\": \"Resource does not exist\",\n \"error\": \"Something Happened\",\n \"report_url\": \"https://github.com...\"\n }\n```\n\n| Property | Remarks |\n| ---- | ---- |\n| `status` | Returned HTTP Status Code |\n| `type` | Thrown Exception |\n| `message` | Human-readable error message |\n| `error` | Error response and trace from the API |\n| `report_url` | Clicking this would redirect you to a generated GitHub issue. ℹ It's only returned on a parser error. |\n\n\n## Cache Validation\n\n- All requests return a `ETag` header which is an MD5 hash of the response\n- You can use this hash to verify if there's new or updated content by suppliying it as the value for the `If-None-Match` in your next request header\n- You will get a HTTP `304 - Not Modified` response if the content has not changed\n- If the content has changed, you'll get a HTTP `200 - OK` response with the updated JSON response\n\n![Cache Validation](https://i.imgur.com/925ozVn.png 'Cache Validation')\n\n## Disclaimer\n\n- Jikan is not affiliated with MyAnimeList.net.\n- Jikan is a free, open-source API. Please use it responsibly.\n\n----\n\nBy using the API, you are agreeing to Jikan's [terms of use](https://jikan.moe/terms) policy.\n\n[v3 Documentation](https://jikan.docs.apiary.io/) - [Wrappers/SDKs](https://github.com/jikan-me/jikan#wrappers) - [Report an issue](https://github.com/jikan-me/jikan-rest/issues/new) - [Host your own server](https://github.com/jikan-me/jikan-rest)",
"description": "[Jikan](https://jikan.moe) is an **Unofficial** MyAnimeList API.\nIt scrapes the website to satisfy the need for a complete API - which MyAnimeList lacks.\n\n# Information\n\n⚡ Jikan is powered by it's awesome backers - 🙏 [Become a backer](https://www.patreon.com/jikan)\n\n## Rate Limiting\n\n| Duration | Requests |\n|----|----|\n| Daily | **Unlimited** |\n| Per Minute | 60 requests |\n| Per Second | 3 requests |\n\nNote: It's still possible to get rate limited from MyAnimeList.net instead.\n\n\n## JSON Notes\n- Any property (except arrays or objects) whose value does not exist or is undetermined, will be `null`.\n- Any array or object property whose value does not exist or is undetermined, will be empty.\n- Any `score` property whose value does not exist or is undetermined, will be `0`.\n- All dates and timestamps are returned in [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) format and in UTC timezone\n\n## Caching\nBy **CACHING**, we refer to the data parsed from MyAnimeList which is stored temporarily on our servers to provide better API performance.\n\nAll requests are cached for **24 hours**.\n\nThe following response headers will detail cache information.\n\n| Header | Remarks |\n| ---- | ---- |\n| `Expires` | Cache expiry date |\n| `Last-Modified` | Cache set date |\n| `X-Request-Fingerprint` | Unique request fingerprint (only for cachable requests, not queries) |\n\n\nNote: `X-Request-Fingerprint` will only be available on single resource requests and their child endpoints. e.g `/anime/1`, `/anime/1/relations`.\nThey won't be available on pages which perform queries, like /anime, or /top/anime, etc.\n\n## Allowed HTTP(s) requests\n\n**Jikan REST API does not provide authenticated requests for MyAnimeList.** This means you can not use it to update your anime/manga list.\nOnly GET requests are supported which return READ-ONLY data.\n\n## HTTP Responses\n\nAll error responses are accompanied by a JSON Error response.\n\n| Exception | HTTP Status | Remarks |\n| ---- | ---- | ---- |\n| N/A | `200 - OK` | The request was successful |\n| N/A | `304 - Not Modified` | You have the latest data (Cache Validation response) |\n| `BadRequestException|ValidationException` | `400 - Bad Request` | You've made an invalid request. Recheck documentation |\n| `BadResponseException` | `404 - Not Found` | The resource was not found or MyAnimeList responded with a `404` |\n| `BadRequestException` | `405 - Method Not Allowed` | Requested Method is not supported for resource. Only `GET` requests are allowed |\n| `RateLimitException` | `429 - Too Many Request` | You are being rate limited by Jikan or MyAnimeList is rate-limiting our servers (specified in the error response) |\n| `UpstreamException|ParserException`, Multiple | `500 - Internal Server Error` | Something didn't work. Try again later. If you see an error response with a `report_url` URL, please click on it to open an auto-generated GitHub issue |\n\n## JSON Error Response\n\n```json\n {\n \"status\": 500,\n \"type\": \"InternalException\",\n \"message\": \"Exception Message\",\n \"error\": \"Exception Trace\",\n \"report_url\": \"https://github.com...\"\n }\n```\n\n| Property | Remarks |\n| ---- | ---- |\n| `status` | Returned HTTP Status Code |\n| `type` | Thrown Exception |\n| `message` | Human-readable error message |\n| `error` | Error response and trace from the API |\n| `report_url` | Clicking this would redirect you to a generated GitHub issue |\n\n\n## Cache Validation\n\n- All requests return a `ETag` header which is an MD5 hash of the response\n- You can use this hash to verify if there's new or updated content by suppliying it as the value for the `If-None-Match` in your next request header\n- You will get a HTTP `304 - Not Modified` response if the content has not changed\n- If the content has changed, you'll get a HTTP `200 - OK` response with the updated JSON response\n\n![Cache Validation](https://i.imgur.com/925ozVn.png 'Cache Validation')\n\n## Disclaimer\n\n- Jikan is not affiliated with MyAnimeList.net.\n- Jikan is a free, open-source API. Please use it responsibly.\n\n----\n\nBy using the API, you are agreeing to Jikan's [terms of use](https://jikan.moe/terms) policy.\n\n[v3 Documentation](https://jikan.docs.apiary.io/) - [Wrappers/SDKs](https://github.com/jikan-me/jikan#wrappers) - [Report an issue](https://github.com/jikan-me/jikan-rest/issues/new) - [Host your own server](https://github.com/jikan-me/jikan-rest)",
"termsOfService": "https://jikan.moe/terms",
"contact": {
"name": "API Support (Discord)",
Expand Down Expand Up @@ -4217,8 +4217,6 @@
"enum": [
"mal_id",
"title",
"type",
"rating",
"start_date",
"end_date",
"episodes",
Expand Down

0 comments on commit d01ed99

Please sign in to comment.