Reputation: 8674
I made the below controller to demonstrate the issue of handling 500 errors I am having with the api. I want to be able to detect when a 500 error will be thrown so it never makes it to the client (as it is too much details to share with the client and they should only be logged by Laravel).
The methodgetUser()
returns a 500 error intentionally due to the typo firsgt()
class TestController extends Controller {
public function getUser() {
$data = User::firsgt(); //returns 500 error
return $data;
}
}
How can we return an error message like 'Error occurred' instead of the too much details for client 'Call to undefined method App\User::firsgt()'?
Note: I don't want to handle it one by one for each controller method, but instead capture any 500 before it is returned to client, and return the custom 500 generic message 'Error occurred'
Upvotes: 0
Views: 4031
Reputation: 3805
If you want to use the message data from the Laravel response, nativiely, you need to look for the response data, where the message is included. This only works when APP_DEBUG=true, this should not be enabled in production, but for clarity:
Suppose you are using axios
to make the request, it would look something like this:
axios.get("/api/catalogs/clients/")
.then(res => {
this.client = res.data;
})
.catch(e => {
print(e.message); //This would print Server error
this.clientError = e.response.data.message; //This will print Call to undefined method
});
Upvotes: 0
Reputation: 1929
Just change the variables in your .env
file to prevent these messages from being sent with the response.
APP_ENV=production
APP_DEBUG=false
Edit: just setting APP_DEBUG
to false is enough.
Update:
If you're using dingo api package, then beside setting APP_DEBUG
to false you need to edit the config file.
If you haven't already done yet, publish dingo config file
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
Then, open config/api.php and edit the errorFormat
value to whatever message you want.
Replace :message
with a generic message
Upvotes: 2
Reputation: 14241
The detailed explanation of the error are shown in develpment environments, for production you don't want to show them -for security reasons- so, as @Hamoud stated, go to your .ENV
file find the line:
APP_DEBUG=true
change it to:
APP_DEBUG=false
This will show only the standard error responses. Check the documentation about error details.
Upvotes: 1
Reputation: 111839
You have app/Exception/Handler.php
class to do this. For example you can use code similar to this:
public function render($request, Exception $e)
{
$exception_class = get_class($e);
if (!in_array($exception_class, [ValidationException::class, ModelNotFoundException::class] ) {
return response()->json(['info' => 'Error occurred'], 500);
}
return parent::render();
}
but as you see you should exclude some exception classes that you would like to be rendered in normal way, here are only some sample exception classes.
Obviously in case you are designing API probably there is no point to use parent::render()
at all and you should handle custom exception classes in custom way and then finally for other exceptions just return 500 response with the message you want.
Upvotes: 2
Reputation: 1234
Laravel already does this for you, but only if you are in production mode and the request is expecting JSON.
Anyhow, the App\Exceptions\Handler class is where all exceptions can be handled. It's also the place where all exceptions are logged and rendered by Laravel itself.
public function render($request, Exception $exception)
{
// your logic here
return parent::render($request, $exception);
}
Upvotes: 1
Reputation: 34914
You can use try ... catch
try{
.....
}catch(\Exception $e){
if($e->getCode() == 500){
return response()->json(["error"=>'$e->getCode()'],500);
}
}
Upvotes: 1