Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MirkoKlefker's avatar

Redirect Execption handle

In an older Laravel version this was working fine. Now in Laravel 10 it never catches the exception.

Now it needs to be catched in the Handler.php, but how to do this correctly?

This is the code which was working fine in Laravel 6.x and PHP 5.4.

        try {
            $results = null;
....
....
....
            if (Request::has('link')) {
                // redirect to a route linked in the http post request or the 'certs'-route
                Session::put($results);

                if ($validate) {
                    return Redirect::to(Request::input('link'))
                    ->with('message.success', 'Validation successful.'); 
                }else {
                    return (Redirect::to(Request::input('link')));
                }
            } else {
                return Redirect::to('certs');
            }
        } catch (CertValidationException $e) {
            // catch any errors that occured duríng validation, store them to our user session.
            Session::put($e->getErrors());
            if ($validate || ($mode == 'select' && $cert->phase != 'select')) {
                // redirect back to 'certs.sections.edit'-route with an error message
                return Redirect::route(
                    'certs.sections.edit',
                    [$certId, $sectionId, $mode]
                )
                    ->with('message.error', 'Validation was not successful. Please correct the errors marked below.');
            } else {
                // redirect to a route linked in the http post request or the 'certs'-route
                if (!$internalSubmit) {
                    if (Request::has('link')) {
                        return Redirect::to(Request::input('link'));
                    } else {
                        return Redirect::to('certs');
                    }
                }
            }
        }
0 likes
5 replies
KalimeroMK's avatar

Handling exceptions in Laravel 10, especially when it comes to redirecting based on specific exceptions, has some nuances compared to older versions like Laravel 6.x. In Laravel 10, exception handling is primarily managed within the Handler.php file located in app/Exceptions.

Here’s a guide on how to adapt your existing exception handling to work with Laravel 10:

  1. Update Your Handler.php File You need to modify the register method in the Handler.php file to catch the CertValidationException and handle the redirections.

Open app/Exceptions/Handler.php. Modify the register Method: Add a custom exception handling logic for CertValidationException.

public function register()
{
    $this->reportable(function (Throwable $e) {
        //
    });

    $this->renderable(function (CertValidationException $e, $request) {
        // Check if it's an AJAX request or a regular request
        if ($request->ajax()) {
            // Handle AJAX-specific response
            return response()->json(['error' => $e->getMessage()], 422);
        } else {
            // Handle regular web response
            Session::put($e->getErrors());

            // Logic similar to your catch block
            // You may need to adjust this part depending on your application logic
            if ($validate || ($mode == 'select' && $cert->phase != 'select')) {
                return redirect()->route('certs.sections.edit', [$certId, $sectionId, $mode])
                    ->with('message.error', 'Validation was not successful. Please correct the errors marked below.');
            } else {
                if (!$internalSubmit) {
                    if ($request->has('link')) {
                        return redirect()->to($request->input('link'));
                    } else {
                        return redirect()->to('certs');
                    }
                }
            }
        }
    });
}
  1. Adjust Your Controller Logic In your controller where you previously had the try-catch block, you can now remove the catch part, as the Handler.php will take care of catching and handling the CertValidationException. Make sure any variable used in the catch block ($validate, $certId, $sectionId, $mode, $internalSubmit) is accessible in the Handler.php. You might need to adjust your application logic to ensure these variables are available where needed.
jaseofspades88's avatar

I love spaghetti, which is ironic considering all this code makes me want to do is throw up!

The framework changes are well documented between versions, including changes to all aspects of the framework. A few suggestions...

  1. Put any individual redirect rules into a middleware class and attach that to your routes.
  2. Put any validation on a form request class and inject that into your controllers.

These tips alone would put lipstick on this pig!

martinbean's avatar
Level 80

@mirkoklefker You’d be better off using the exception handler properly, rather than trying to get back undocumented and unintentional behaviour from an ancient version of the framework.

You‘re throwing a “domain” exception (good). You can leverage the exception handler to automatically convert this to a validation exception if it’s thrown in a HTTP context:

public function handle()
{
    $this->renderable(function (CertValidationException $e) {
        throw ValidationException::withMessages([
            'field_1' => [
                'Some error message.',
            ],
            'field_2' => [
                'Some other error message.',
            ],
        ]);
    });
}

If your getErrors method returns an array of fields, and an array of error messages for each field, then you could use that in the withMessage method:

throw ValidationException::withMessages($e->getErrors());

This will automatically add the errors to the session, and redirect back to the previous URL as if it were a “normal” validation failure, meaning you can clean up your controllers by removing unnecessary try/catch blocks:

public function someAction(SomeRequest $request)
{
    // Handle request...
    // Return response...
}

Your controller actions then just become concerned with its actual job (handling the incoming request) rather than having to do error handling logic as well. Handling exceptions is what the exception handler is for, as its name suggests.

ripper121's avatar

I have many files where a "throw new CertValidationException($validationResults);" and also many different files where these need to be handled differently

For example:

        $this->query_info('ENTER CertUpdateCommandHandler::validate - '.$section->number);
		$validator = App::make('CertTool\Certs\CertValidator');
		$validationResults = [];
		if ($validator->validateSection($cert, $section, $this->mode, $validationResults)) {
            $this->query_info(' -- throw validation exception');
            throw new CertValidationException($validationResults); 
        } else {
            $this->query_info(' -- return validation result');
            return $validationResults;
        }
    }

in another File I use it like this

    public function validateForCreate($attributes)
    {
        $validationResults = [];
        $hasErrors = false;

        $hasErrors |= $this->validateProductDetails($attributes, $validationResults) == false;        

        $hasErrors |= $this->validateCertType($attributes, $validationResults) == false;

        $hasErrors |= $this->validateChipVendorData($attributes, $validationResults) == false;

        $hasErrors |= $this->validateTestPartner($attributes, $validationResults) == false;
        

        if ($hasErrors) {
            throw new CertValidationException($validationResults);
        } else {
        	return $validationResults;
        }
    }

Then I need to catch these errors also in different files:

        try {
            $certValidator = new CertValidator($this);
            $certValidator->validateForUpdate($attributes);
        } catch (CertValidationException $e)
        {
            $messages = $e->getErrors();
        }

In another file:

			try {
				$this->validateForCreate($attributes);
				Session::put("validation.$cert->id.general.section", false);
			} catch (CertValidationException $e)
			{
				Session::put("validation.$cert->id.general.section", true);
				if (!Config::get('app.demo_mode')) {
					$hasErrors = true;
				}
			}

How can I handle this problem in the Handler.php ... ?

Please or to participate in this conversation.