I am working with the Laravel 9 application. I have created a custom Exception. I want to report the General Exception to the sentry and this custom Exception to another vendor like Papertrail.
The Handler.php is not calling the reportable closure function when the application throws a custom exception i.e ServiceException.
By the way, the Laravel documentation for errors is also not understandable
Handler.php
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Inertia\Inertia;
use Throwable;
use Exception;
use App\Exceptions\ServiceException;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
// ServiceException::class
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->reportable(function (Throwable $e) {
// this block is calling for Exception but not for custom Exception like ServiceException.
if ($this->shouldReport($e) && app()->bound('sentry')) {
app('sentry')->captureException($e);
}
});
$this->reportable(function (ServiceException $e) {
// this block is not calling when I throw ServiceException.
echo "Send this ServiceException to papertrail app."; // this line is never called.
die;
});
}
public function render($request, Throwable $e)
{
$response = parent::render($request, $e);
if ($request->isJson()) {
//prevent error for local and staging.
if (! app()->environment(['local', 'staging']) && in_array($response->status(), [500, 503, 404, 403])) {
\Log::error('API Error Handler', [$response->getOriginalContent()]);
$message = trans('message.error_description_500');
if ($response->status() == 404) {
$message = trans('message.data_not_found');
} elseif ($response->status() == 403) {
$message = trans('message.you_are_not_allowed_perform');
} elseif ($response->status() == 503) {
$message = trans('message.error_description_503');
}
return response()->json([
'message' => $message,
], $response->status());
}
}
return $response;
}
}
ServiceException.php
<?php
namespace App\Exceptions;
use Exception;
class ServiceException extends Exception
{
/**
* Report the exception.
*
* @return void
*/
public function report()
{
//
}
/**
* Render the exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function render($request, $exception)
{
if (! $request->ajax()) {
// view('error_handler', compact('exception'));
}
return response()->json([
'code' => $exception->getCode(),
'status' => 'error',
'message' => $exception->getMessage(),
'data' => 'sample data',
]);
}
}
AnyController.php
public function anyFunction() {
// throw new Exception('Unhandled Exception.'); // It will call the $this->reportable(function (Throwable $e) { block.
// throw new ServiceException('Unhandled ServiceException.'); // It will call the $this->reportable(function (Throwable $e) { block.
try {
$this->service->aFunctionThatThrowException(); // this function will throw ServiceException.
} catch (Exception $e) {
Log::error('controller_fun_error', ['error' => $e->getMessage()]);
report($e);
return $this->failResponse();
}
}
AnyService.php
public function aFunctionThatThrowException() {
try {
throw new ServiceException('Throwing ServiceException...)');
} catch (ServiceException | Exception $e) {
Log::error('service_fun_error', ['error' => $e->getMessage()]);
throw $e;
}
}