Mohamed Kamel
Mohamed Kamel

Reputation: 161

Lumen 5.6 Error handling (throws exception twice)

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?

Upvotes: 1

Views: 2251

Answers (1)

Mohamed Kamel
Mohamed Kamel

Reputation: 161

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

Upvotes: 2

Related Questions