Lumen 5.6 Error handling (throws exception twice)

2.2k Views Asked by At

This is my code to handle any error:

App\Exceptions\Handler::class

public function render($request, Exception $e)
{

    $fe = \Symfony\Component\Debug\Exception\FlattenException::create($e);

    $statusCode = $fe->getStatusCode();
    $code       = $fe->getCode();
    $message    = $fe->getMessage();

    $errorObj = new \App\LOHDomain\Entities\Error($code, $message);

    return response()->json(['data' => null, 'error' => $errorObj], $statusCode);
}

when I parse a fake WSDL URL to the SoapClient it throws two exceptions

{"data":null,"error":{"code":"0","message":"SOAP-ERROR: Parsing WSDL: Couldn't load from 'asdsd' : failed to load external entity \"asdsd\"\n"}}
{"data":null,"error":{"code":"1","message":"SOAP-ERROR: Parsing WSDL: Couldn't load from 'asdsd' : failed to load external entity \"asdsd\"\n"}}

So the json response became invalid

When commenting these line of codes in the vendor, it throws one exception:

Laravel\Lumen\Concerns\RegistersExceptionHandlers trait

protected function registerErrorHandling()
{
        error_reporting(-1);

        set_error_handler(function ($level, $message, $file = '', $line = 0) {
            if (error_reporting() & $level) {
                throw new ErrorException($message, 0, $level, $file, $line);
            }
        });

        set_exception_handler(function ($e) {
            $this->handleUncaughtException($e);
        });

//        register_shutdown_function(function () {
//            $this->handleShutdown();
//        });
}

So, What is the problem? and how to solve it without editing in the vendor?

1

There are 1 best solutions below

0
Mohamed Kamel On BEST ANSWER

The solution is to clear the last error, because it fired twice.

  1. The error exception.
  2. The second is the shutdown function.

So, the solution is:

App\Exceptions\Handler::class

public function render($request, Exception $e)
{

    $fe = \Symfony\Component\Debug\Exception\FlattenException::create($e);

    $statusCode = $fe->getStatusCode();
    $code       = $fe->getCode();
    $message    = $fe->getMessage();

    $errorObj = new \App\Domain\Entities\ResponseEntites\Error($code, $message);

    /**
     * This line of code resolves the issue
     * 
     * To reproduce the issue :
     * 1) Comment this following line of code
     * 2) Provide a fake WSDL URL to the SoapClient
     *
     * Recommendation: Remove this line if you aren't using the SoapClient
     */
    error_clear_last();

    return new \Illuminate\Http\JsonResponse(['data' => null, 'error' => $errorObj], $statusCode);
}

This isn't the best solution (but this is the best solution, that I tried in my case). If you have a better tested solution please share it.

links:

  1. Fatal exceptions are handled twice
  2. Code change