mirror of
https://github.com/jikan-me/jikan-rest.git
synced 2025-02-20 11:23:35 +08:00
improves sentry integration and order of exceptions
This commit is contained in:
parent
91ced83394
commit
072409410e
@ -121,12 +121,12 @@ INSIGHTS_MAX_STORE_TIME=172800
|
||||
###
|
||||
# Error reporting
|
||||
###
|
||||
REPORTING=true
|
||||
REPORTING=false
|
||||
REPORTING_DRIVER=sentry
|
||||
SENTRY_LARAVEL_DSN="https://examplePublicKey@o0.ingest.sentry.io/0"
|
||||
SENTRY_TRACES_SAMPLE_RATE=1
|
||||
SENTRY_TRACES_SAMPLE_RATE=0.5
|
||||
|
||||
###
|
||||
# Endpoints
|
||||
###
|
||||
DISABLE_USER_LISTS=false
|
||||
DISABLE_USER_LISTS=false
|
||||
|
@ -15,54 +15,54 @@ class GithubReport
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
private string $name;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $code;
|
||||
private string $code;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $error;
|
||||
private string $error;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $requestUri;
|
||||
private string $requestUri;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $requestMethod;
|
||||
private string $requestMethod;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $repo;
|
||||
private string $repo;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $trace;
|
||||
private string $trace;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $jikanVersion;
|
||||
private string $jikanVersion;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $redisRunning;
|
||||
private string $redisRunning;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $instanceType;
|
||||
private string $instanceType;
|
||||
|
||||
/**
|
||||
* @var
|
||||
* @var string
|
||||
*/
|
||||
private $phpVersion;
|
||||
private string $phpVersion;
|
||||
|
||||
/**
|
||||
* @param \Exception $exception
|
||||
|
@ -3,10 +3,7 @@
|
||||
namespace App\Exceptions;
|
||||
|
||||
use App\Events\SourceHeartbeatEvent;
|
||||
use App\Http\HttpHelper;
|
||||
use Exception;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@ -16,11 +13,9 @@ use Jikan\Exception\BadResponseException;
|
||||
use Jikan\Exception\ParserException;
|
||||
use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
|
||||
use Predis\Connection\ConnectionException;
|
||||
use Symfony\Component\Debug\Exception\FlattenException;
|
||||
use Symfony\Component\HttpClient\Exception\TimeoutException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
@ -41,6 +36,13 @@ class Handler extends ExceptionHandler
|
||||
BadResponseException::class
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected array $acceptableForReportingDriver = [
|
||||
ParserException::class
|
||||
];
|
||||
|
||||
/**
|
||||
* @param \Throwable $e
|
||||
* @throws Exception
|
||||
@ -55,13 +57,10 @@ class Handler extends ExceptionHandler
|
||||
* @param \Throwable $e
|
||||
* @return JsonResponse|Response
|
||||
*/
|
||||
public function render($request, \Throwable $e)
|
||||
public function render($request, \Throwable $e): JsonResponse|Response
|
||||
{
|
||||
$githubReport = GithubReport::make($e, $request);
|
||||
|
||||
if (app()->bound('sentry') && $this->shouldReport($e)) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
$this->reportToSentry($e);
|
||||
|
||||
// ConnectionException from Redis server
|
||||
if ($e instanceof ConnectionException) {
|
||||
@ -83,18 +82,6 @@ class Handler extends ExceptionHandler
|
||||
], 500);
|
||||
}
|
||||
|
||||
if ($e instanceof ConnectException) {
|
||||
event(new SourceHeartbeatEvent(SourceHeartbeatEvent::BAD_HEALTH, $e->getCode()));
|
||||
|
||||
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.',
|
||||
'error' => $e->getMessage()
|
||||
], 503);
|
||||
}
|
||||
|
||||
// ParserException from Jikan PHP API
|
||||
if ($e instanceof ParserException) {
|
||||
$githubReport->setRepo(env('GITHUB_API', 'jikan-me/jikan'));
|
||||
@ -108,9 +95,9 @@ class Handler extends ExceptionHandler
|
||||
], 500);
|
||||
}
|
||||
|
||||
// BadResponseException from Guzzle dep via Jikan PHP API
|
||||
// BadResponseException from Jikan PHP API
|
||||
// This is basically the response MyAnimeList returns to Jikan
|
||||
if ($e instanceof BadResponseException || $e instanceof ClientException) {
|
||||
if ($e instanceof BadResponseException) {
|
||||
switch ($e->getCode()) {
|
||||
case 404:
|
||||
// $this->set404Cache($request, $e);
|
||||
@ -157,6 +144,28 @@ class Handler extends ExceptionHandler
|
||||
}
|
||||
}
|
||||
|
||||
if ($e instanceof TimeoutException) {
|
||||
return response()
|
||||
->json([
|
||||
'status' => 408,
|
||||
'type' => 'TimeoutException',
|
||||
'message' => 'Request to MyAnimeList.net timed out (' .env('SOURCE_TIMEOUT', 5) . ' seconds)',
|
||||
'error' => $e->getMessage()
|
||||
], 408);
|
||||
}
|
||||
|
||||
if ($e instanceof Exception && $e->getMessage() === "Undefined index: url") {
|
||||
event(new SourceHeartbeatEvent(SourceHeartbeatEvent::BAD_HEALTH, $e->getCode()));
|
||||
|
||||
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!',
|
||||
'error' => $e->getMessage()
|
||||
], 503);
|
||||
}
|
||||
|
||||
// Bad REST API requests
|
||||
if ($e instanceof HttpException) {
|
||||
return response()
|
||||
@ -168,71 +177,32 @@ class Handler extends ExceptionHandler
|
||||
], $e->getStatusCode());
|
||||
}
|
||||
|
||||
if ($e instanceof TimeoutException) {
|
||||
return response()
|
||||
->json([
|
||||
'status' => 408,
|
||||
'type' => 'TimeoutException',
|
||||
'message' => 'Request to MyAnimeList.net timed out (' .env('SOURCE_TIMEOUT', 5) . ' seconds)',
|
||||
'error' => $e->getMessage()
|
||||
], 408);
|
||||
}
|
||||
|
||||
if ($e instanceof Exception) {
|
||||
if ($e->getMessage() === "Undefined index: url") {
|
||||
event(new SourceHeartbeatEvent(SourceHeartbeatEvent::BAD_HEALTH, $e->getCode()));
|
||||
|
||||
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!',
|
||||
'error' => $e->getMessage()
|
||||
], 503);
|
||||
}
|
||||
|
||||
|
||||
return response()
|
||||
->json([
|
||||
'status' => 500,
|
||||
'type' => "Exception",
|
||||
'message' => 'Unhandled Exception. Please follow report_url to generate an issue on GitHub',
|
||||
'trace' => "{$e->getFile()} at line {$e->getLine()}",
|
||||
'error' => $e->getMessage(),
|
||||
'report_url' => env('GITHUB_REPORTING', true) ? (string) $githubReport : null
|
||||
], 500);
|
||||
}
|
||||
return response()
|
||||
->json([
|
||||
'status' => 500,
|
||||
'type' => "Exception",
|
||||
'message' => 'Unhandled Exception. Please follow report_url to generate an issue on GitHub',
|
||||
'trace' => "{$e->getFile()} at line {$e->getLine()}",
|
||||
'error' => $e->getMessage(),
|
||||
'report_url' => env('GITHUB_REPORTING', true) ? (string) $githubReport : null
|
||||
], 500);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param BadResponseException $e
|
||||
* @param Exception|\Throwable $e
|
||||
* @return void
|
||||
*/
|
||||
private function set404Cache(Request $request, BadResponseException $e)
|
||||
private function reportToSentry(\Exception|\Throwable $e): void
|
||||
{
|
||||
if (!env('CACHING') || env('MICROCACHING')) {
|
||||
if (!app()->bound('sentry')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fingerprint = "request:404:".sha1(env('APP_URL') . $request->getRequestUri());
|
||||
|
||||
if (Cache::has($fingerprint)) {
|
||||
return;
|
||||
foreach ($this->acceptableForReportingDriver as $type) {
|
||||
if ($e instanceof $type) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
}
|
||||
|
||||
$routeController = HttpHelper::requestControllerName($request);
|
||||
$cacheTtl = env('CACHE_DEFAULT_EXPIRE', 86400);
|
||||
|
||||
if (\in_array($routeController, [
|
||||
'AnimeController',
|
||||
'MangaController',
|
||||
'CharacterController',
|
||||
'PersonController'
|
||||
])) {
|
||||
$cacheTtl = env('CACHE_404_EXPIRE', 604800);
|
||||
}
|
||||
|
||||
|
||||
Cache::put($fingerprint, $e->getMessage(), $cacheTtl);
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,11 @@ if (env('REPORTING') && env('REPORTING_DRIVER') === 'sentry') {
|
||||
$app->register(\Sentry\Laravel\ServiceProvider::class);
|
||||
// Sentry Performance Monitoring (optional)
|
||||
$app->register(\Sentry\Laravel\Tracing\ServiceProvider::class);
|
||||
|
||||
\Sentry\configureScope(function (\Sentry\State\Scope $scope): void {
|
||||
$scope->setTag('rest.jikan.version', env('APP_VERSION'));
|
||||
$scope->setTag('parser.jikan.version', JIKAN_PARSER_VERSION);
|
||||
});
|
||||
}
|
||||
|
||||
// Guzzle removed as of lumen 8.x
|
||||
|
@ -8,7 +8,7 @@ return [
|
||||
// 'release' => trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')),
|
||||
|
||||
// When left empty or `null` the Laravel environment will be used
|
||||
'environment' => env('SENTRY_ENVIRONMENT'),
|
||||
'environment' => env('APP_ENV'),
|
||||
|
||||
'breadcrumbs' => [
|
||||
// Capture Laravel logs in breadcrumbs
|
||||
@ -54,4 +54,6 @@ return [
|
||||
|
||||
'controllers_base_namespace' => env('SENTRY_CONTROLLERS_BASE_NAMESPACE', 'App\\Http\\Controllers'),
|
||||
|
||||
'release' => env('APP_VERSION')
|
||||
|
||||
];
|
||||
|
Loading…
x
Reference in New Issue
Block a user