How to exclude logging an Guzzle's 404 error in Laravel? - laravel

I use the Laravel framework. When I get an exception GuzzleHttp\\Exception\\ClientException(code: 404), this event is added to laravel.log. How can I disable adding the event about that error to laravel.log?

You can remove it from the exceptions handler file according to the docs, if can be found in your App\Exceptions\Handler so for example:-
use GuzzleHttp\Exception\ClientException; // here, import the target class
...
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* #var string[]
*/
protected $dontReport = [
ClientException::class, // here, add the class to the don't report list
];
...
}
to manipulate a custom error condition, you can register it in the register method in the Handler file like:-
**
* Register the exception handling callbacks for the application.
*
* #return void
*/
public function register()
{
// check if the ClientExeption is a 404
$this->reportable(function (ClientException $e) {
if ($e->getCode() == 404) {
return false; // or anything else for that matter
}
});
}

Related

Best way to handling a custom error in queued listener on laravel

I have a listener in laravel 9 that transfer posts, but I want to handle a custom error if the destination user is deleted
my listener currently implements ShouldQueue and actually in my method handle I have this
public function handle(TransferPostEvent $transferPostsEvent)
{
$toUser = $this->userService->getUserById($transferPostsEvent->toUserId);
if ($toUser->trashed()) {
$errorMessage = ('*** DESTINATION USER WAS DELETED BEFORE TRANSFER THE POST user id: ' . $toUser->id . '***');
$errorException = new Exception(message: $errorMessage);
$this->failed($transferPostsEvent, $errorException);
} else {
//transfer post...
}
}
and this is my failed method
/**
* #param TransferPostEvent $event
* #param \Throwable $exception
*/
public function failed(TransferPostEvent $event, \Throwable $exception)
{
Log::error($exception);
}
It seems fine, logs are ok, but the console shows 'Processed:Modules\Admin\Listeners\TransferPostListener' message and I would like to show 'Failed:'? is it ok to show 'Failed:' in the console for this type of error? How could I cause it manually?

laravel return exception as json instead of an html

I have an old Laravel app that is upgraded to v7. Currently exceptions are returned as an HTML page. But I would like them to be returned as json response. I understand that exceptions are handled in Exceptions\Handler.php:
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* #var array<int, class-string<Throwable>>
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* #var array<int, string>
*/
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) {
});
}
}
How can I return the whole exception sack as json?
Edit: The app is old and was using a custom exception handler. Now after the upgrade to V.7 it would be nice to use the default exception handler so that exceptions are returned in json.
Edit 2:
When I use
return response()->json([
'exception' =>exception,
]);
I get an empty object. I don't want to only return the message of the exception but the whole exception stack.
You can override render function inside App\Exceptions\Handler.php
and you can read more about it https://laravel.com/docs/7.x/errors#render-method

Need to Handle Laravel Exception and, Logging details mismatch error

I have tried to handle the exceptions on Handler class in my laravel project
if(!env('APP_DEBUG', false)){
return view('errors.500');
} else {
return parent::render($request, $exception);
}
Errors are redirecting to my page. but in the login page user name or password mismatch also redirecting to that page.
in the login error need to redirect to the login page,not to the common error page. how can handle it?
i have using default laravel auth login.
this is my Handler.php file,
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* #var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* #var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* #param \Exception $exception
* #return void
*/
public function report(Exception $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $exception
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
// Render well-known exceptions here
// Otherwise display internal error message
if(!env('APP_DEBUG', false)){
return view('errors.500');
} else {
return parent::render($request, $exception);
}
}
}
no need to check for 500 errors manually .If you want to show custom error message for 500 erorrs in production then publish default laravel views for errors
php artisan vendor:publish --tag=laravel-errors
This will generate views for errors in following path
resources/views/errors
To customize 500 erorrs .Edit following path
resources/views/errors/500.blade.php
Also make sure this will only show when
APP_DEBUG=false

How to delegate exception to global exception in Laravel?

There is typical code in controller Laravel:
public function create(CreateInvoiceRequest $request)
{
try {
$invoice = Invoice::create(['']);
return response()->json($model);
} catch (\Exception $e) {
return \Response::json(["errors" => $e->getMessage()], 400);
}
}
In exception case I catch it and show message, how to delagate (move) this in global exception Laravel? Need I do something like this?
try { } } catch (\Exception $e) { throw new Exception($e); }
Laravel has a nice solution for this. In the documentation we are told to do this kind of exception handeling in App\Exceptions\Handler.
A very simple example could be the following:
// Your controller.
try {
$invoice = Invoice::create(['']);
return response()->json($model);
} catch (\Exception $e) {
throw new CustomException('Invoice creation failed.');
}
// app\Exceptions\Handler.php
public function render($request, Exception $exception)
{
if ($exception instanceof CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $exception);
}
I tried to find out if create would throw a specific exception. Unfortunately I could not find it out so quickly. If this was the case, you could remove the try catch and just listen to this specific exception in the render method.
Update
(not tested)
In addition, you can also overwrite the save method to prevent from having to wrap (all) database writing method calls with a try and catch.
We will need a BaseModel class:
<?php
namespace App\Models;
use App\Exceptions\ModelSaveException;
use Illuminate\Database\Eloquent\Model as EloquentModel;
class Model extends EloquentModel
{
/**
* Save the model to the database.
*
* #param array $options
* #return bool
* #throws \App\Exceptions\ModelSaveException
*/
public function save(array $options = [])
{
try {
return parent::save($options);
} catch(\Exception $e) {
throw new ModelSaveException($this);
}
}
}
Your controller will look cleaner without try catch:
$invoice = Invoice::create(['']);
return response()->json($model);
As an extra we can check if our model was being created of updated by making is of the exists property.
<?php
namespace App\Exceptions;
class ModelSaveException extends \Exception
{
/**
* ModelSaveException constructor.
*
* #param \Illuminate\Database\Eloquent\Model $model
* #return void
*/
public function __construct($model)
{
if ($model->exists) {
parent::__construct('Failed updating model.');
} else {
parent::__construct('Failed creating model.');
}
}
}
Ofcourse don't forget to extend from you newly created model:
use App\Models\Model;
class Invoice extends Model
You can create a custom renderable exception.
try {
// Your code...
} catch (\Exception $e) {
throw new \App\Exceptions\CustomException('Your message');
}
Instead of type-checking exceptions in the exception handler's report and render methods, you may define report and render methods directly on your custom exception. When these methods exist, they will be called automatically by the framework:
/**
* Report the exception.
*
* #return void
*/
public function report()
{
//
}
/**
* Render the exception into an HTTP response.
*
* #param \Illuminate\Http\Request
* #return \Illuminate\Http\Response
*/
public function render($request)
{
return response(...);
}
For more information: https://laravel.com/docs/5.8/errors#renderable-exceptions

How to catch errors and best practices?

I'm performing various tasks on an eloquent model.
e.g.
Flight Repository
function store($request){
$flight = new Flight;
$flight->name = $request->name;
$flight->save();
}
This method is called from a controller:
public function store(FlightRepository $flight, $request){
$flight->store($request);
}
How should one approach potential errors? try/catch? Where should it be placed in the controller or repository? What would I catch anyway, what exception type?
According to Laravel 5.0 and above,
All the Exceptions thrown in any part of the Laravel App, the exceptions are catched inside the report() method of Exception/Handler.php file, like this:
UPDATED
Your Repo should throw an Exception like this:
class CustomRepository extends Repository
{
public function repoMethod($id)
{
$model = Model::find($id);
// Throw your custom exception here ...
if(!$model) {
throw new CustomException("My Custom Message");
}
}
}
And your Handler should handle the CustomException like this:
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* #param \Exception $exception
* #return void
*/
public function report(Exception $exception)
{
// Handle your exceptions here...
if($exception instanceof CustomException)
return view('your_desired_view')->with('message' => $exception->getMessage());
parent::report($exception);
}
Hope this helps!

Resources