Search code examples
laravelexceptionrenderhandlerlaravel-5.5

Laravel - Catch exception in custom handler


I'm using Laravel 5.5 and I want to handle my custom exceptions from custom handlers, not from app\Exceptions\Handler.php. Now, I catch an exception if some field it's empty in the form submitted by the user. It's perfectly working like this:

  1. ProfileController.php:

    public function update(Request $request, $id){
        $this->guzzleService->put(
            $request,
            ApiEndPoints::UPDATE_PROFILE . $id,
            true
        );
    
        return back()->with('SavedCorrectly', 'Changes saved correctly');
    }
    
  2. app\Exceptions\Handler.php

    public function render($request, Exception $exception)
    {
        if($exception instanceof ClientException && $exception->getCode() == 422)
            return back()->withErrors(
                json_decode((string) $exception->getResponse()->getBody(), TRUE)["errors"]
            );
    
        return parent::render($request, $exception);
    }
    

The problem is that I want to refactor that, so that it remains like this:

  1. ProfileController.php

    public function update(Request $request, $id){
        try {
            $this->guzzleService->put(
                $request,
                ApiEndPoints::UPDATE_PROFILE . $id,
                true
            );
    
            return back()->with('SavedCorrectly', 'Cambios guardados correctamente');
        } catch(ClientException $exception) {
            if ($exception->getCode() == 500) throw new InternalServerErrorException;
            if ($exception->getCode() == 422) throw new UnprocessableEntityException;
        }
    }
    
  2. app\Exceptions\HttpExceptions\UnprocessableEntityException.php

    <?php
    
    namespace App\Exceptions\HttpExceptions;
    
    use GuzzleHttp\Exception\ClientException;
    
    class UnprocessableEntityException extends \Exception
    {
        public function render($request, ClientException $exception)
        {
            return back()->withErrors(
                json_decode((string) $exception->getResponse()->getBody(), TRUE)["errors"]
            );
        }
    }
    

But I'm receiving this error:

Type error: Argument 2 passed to App\Exceptions\HttpExceptions\UnprocessableEntityException::render() must be an instance of GuzzleHttp\Exception\ClientException, none given, called in ... \vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php on line 169


Solution

  • this is because you are passing a new exception

    public function update(Request $request, $id){
        try {
            $this->guzzleService->put(
                $request,
                ApiEndPoints::UPDATE_PROFILE . $id,
                true
            );
    
            return back()->with('SavedCorrectly', 'Cambios guardados correctamente');
        } catch(ClientException $exception) {
            if ($exception->getCode() == 500) throw new InternalServerErrorException((string) $exception->getResponse()->getBody());
            if ($exception->getCode() == 422) throw new UnprocessableEntityException((string) $exception->getResponse()->getBody());
        }
    }
    

    and

    <?php
    
    namespace App\Exceptions\HttpExceptions;
    
    use GuzzleHttp\Exception\ClientException;
    
    class UnprocessableEntityException extends \Exception
    {
        public function render($request)
        {
            return back()->withErrors(
                json_decode((string) $this->message, TRUE)["errors"]
            );
        }
    }