Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API exceptions in Laravel 5

I'd like to catch all ordinary exceptions (instances of Exception class) from one of my controllers (or in future in several controllers) to unify their behavior. I know how to make global handlers for exceptions in Exceptions/Handler.php, but how can I limit them to some particular controller?

What I want to do is to return such an array in JSON format whenever Exception is being thrown in my API controller:

[
    'error' => 'Internal error occurred.'
]

I could decide to throw my own exception class, perhaps ApiException, but I want to serve third party exceptions as well, such as database errors.

Should I pass some value to the request object directly? If so, how? Or maybe there's another way?

like image 407
Robo Robok Avatar asked Apr 27 '15 09:04

Robo Robok


3 Answers

If you want to render a different type of exception for a specific controller, you can use the request object to check the current controller :

Exceptions/Handler.php

public function render($request, Exception $e)
{
    if($request->route()->getAction()["controller"] == "App\Http\Controllers\ApiController@index"){
        return response()->json(["error" => "An internal error occured"]);
    }
    return parent::render($request, $e);
}
like image 115
Needpoule Avatar answered Oct 12 '22 07:10

Needpoule


You can do this:

create an exception class

class APIException extends Exception{

}

then throw it from the controller

throw new APIException('api exception');

and catch it from Exceptions/Handler.php

public function render($request, Exception $e)
{
    if ($e instanceof APIException){
        return response(['success' => false, 'data' => [], 'message' => $e->getMessage(), 401);
    }
    if ($e instanceof SomeException){
        return response(['success' => false, 'data' => [], 'message' => 'Exception'], 401);
    }

    return parent::render($request, $e);
}
like image 25
astroanu Avatar answered Oct 12 '22 06:10

astroanu


You can also filter by the request by their path patterns.

Go to the file app\Exceptions\Handler.php:

public function render($request, \Exception $e)
{
    /* Filter the requests made on the API path */
    if ($request->is('api/*')) {
        return response()->json(["error" => "An internal error occurred"]);
    }

    return parent::render($request, $e);
}
like image 42
tzi Avatar answered Oct 12 '22 07:10

tzi