0

For example in my REST Json API: When I call a route with route model binding and pass an invalid id I get:

{
    "message": "No query results for model [App\\Models\\User].",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException",
    "file": "D:\\allianz\\backend\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Exceptions\\Handler.php",
    "line": 199,
    "trace": [
        { ...

However I would prefer not to show this to the API consumer. (Or just the message).

Chris
  • 13,100
  • 23
  • 79
  • 162

3 Answers3

1

You can always catch the exception in the App\Exceptions\Handler.php

Import the exception into the class using the following:

use \Illuminate\Database\Eloquent\ModelNotFoundException;

and in the render method, add

if ($e instanceof ModelNotFoundException) {
    return response()->json([
        'message' => 'Record not found', //or modify it to display whatever message you want here
    ], 404);
}
Latheesan
  • 23,247
  • 32
  • 107
  • 201
pseudoanime
  • 1,547
  • 12
  • 19
1

What is you APP_ENV variable set at? I believe the call stack won't be returned when it's in production.

David Heremans
  • 631
  • 1
  • 5
  • 26
  • 1
    Thanks for pointing me in the right direction. However it depends on APP_DEBUG rather than APP_ENV – Chris Nov 03 '17 at 12:42
0

Although this question was asked in the last century, I like to leave an answer for Laravel 9.7.0.

This answer shows how to globally set how unhandled exceptions should be rendered in http-responses.

I changed the code a bit to return the exception-info without a stack-trace:

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    $this->renderable(function (Throwable $e, $request) {
        $env = config("app.env");

        $msg = $e->getMessage() . " in file '" . $e->getFile() . "' on line '" . $e->getLine() . "'";

        if ($request->is('api/*')) {
            if (strcmp($env, "debug") == 0) {
                return response()->make($msg.$e->getTraceAsString(), 500);
            } else {
                return response()->json([
                    'message' => $msg
                ], 500);
            }
        }
    });
}

So if I set APP_ENV=debug in the .env-file the stacktrace will be added to the repsonse text-message. It's text because I did not test how the stacktrace would mess with the consumers json interpreter. If APP_ENV != debug, the response is a json object with a message-value containing the message, file and linenumber.

JackLeEmmerdeur
  • 724
  • 11
  • 17