Wonka
Wonka

Reputation: 8674

Laravel 5.5 - Only log 500 error, never send error details via api?

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;
  }
}

This is what the client sees: enter image description here

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

Answers (6)

JoeGalind
JoeGalind

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

Hamoud
Hamoud

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

Kenny Horna
Kenny Horna

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

Marcin Nabiałek
Marcin Nabiałek

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

Sher Afgan
Sher Afgan

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

Niklesh Raut
Niklesh Raut

Reputation: 34914

You can use try ... catch

try{
   .....
}catch(\Exception $e){
  if($e->getCode() == 500){
      return response()->json(["error"=>'$e->getCode()'],500);
  }
}

Upvotes: 1

Related Questions