Handling Exceptions in laravel: Tips and Tricks

Moumen Alisawe
5 min readApr 19, 2023

--

Laravel is a popular PHP framework that provides a simple and elegant way to build web applications. One of the features that makes Laravel stand out is its built-in error and exception handling system. In this article, we will explore some tips and tricks on how to handle exceptions in Laravel effectively.

What are exceptions?

Exceptions are errors that occur during the execution of a program that disrupt the normal flow of control. For example, trying to access a non-existent property of an object, dividing by zero, or calling a function with invalid arguments are all examples of exceptions.

Exceptions can be either thrown by the PHP engine itself (such as ParseError or TypeError) or by the application code (such as InvalidArgumentException or ModelNotFoundException). Exceptions can also be custom-defined by extending the base Exception class or any of its subclasses.

How does Laravel handle exceptions?

When you start a new Laravel project, error and exception handling is already configured for you. The App\Exceptions\Handler class is where all exceptions thrown by your application are logged and then rendered to the user. We’ll dive deeper into this class throughout this article1.

By default, Laravel converts all exceptions into HTTP responses with appropriate status codes and error messages. For example, a 404 Not Found exception will result in a 404 HTTP response with a “Not Found” message. A 500 Internal Server Error exception will result in a 500 HTTP response with a “Whoops, something went wrong” message.

Laravel also provides a convenient way to display custom error pages for different HTTP status codes. For example, you can create a resources/views/errors/404.blade.php file to customize the 404 error page. You can use any Blade template features in your error pages, such as layouts, components, or helpers.

How to throw exceptions in Laravel?

Sometimes, you may want to throw an exception manually in your application code to indicate that something went wrong or that some condition was not met. For example, you may want to throw an exception if a user tries to access a resource that they are not authorized to view.

To throw an exception in Laravel, you can use the throw keyword followed by an instance of an exception class. For example:

public function show($id)
{
$post = Post::find($id);

if ($post == null) {
// Throw an exception if the post does not exist
throw new ModelNotFoundException('Post not found');
}

if (Auth::user()->cannot('view', $post)) {
// Throw an exception if the user is not authorized to view the post
throw new AuthorizationException('You are not allowed to view this post');
}

return view('posts.show', compact('post'));
}

You can also use the abort helper function to throw an exception with a given HTTP status code and an optional message. For example:

public function update(Request $request, $id)
{
$post = Post::find($id);

if ($post == null) {
// Abort with a 404 status code and a custom message
abort(404, 'Post not found');
}

if (Auth::user()->cannot('update', $post)) {
// Abort with a 403 status code and a default message
abort(403);
}

// Update the post ...
}

How to catch exceptions in Laravel?

Sometimes, you may want to catch an exception and handle it differently than the default behavior. For example, you may want to log some additional information, perform some cleanup actions, or redirect the user to another page.

To catch an exception in Laravel, you can use the try-catch-finally blocks. The try block contains the code that may throw an exception. The catch block contains the code that will execute if an exception is thrown. The finally block contains the code that will always execute regardless of whether an exception is thrown or not. For example:

try {
// Try to charge the user's credit card ...
} catch (PaymentFailedException $e) {
// Catch and handle the payment failure exception ...
} finally {
// Always release any resources ...
}

How to customize exception handling in Laravel?

Laravel provides a powerful and flexible way to customize how exceptions are handled in your application. The App\Exceptions\Handler class is the central place where you can register your custom exception handling logic.

The Handler class has two methods: report and render. The report method is responsible for logging the exception or sending it to an external service like Bugsnag or Sentry. The render method is responsible for converting the exception into an HTTP response that will be sent back to the user.

You can override these methods in your Handler class to customize their behavior. For example, you can add some additional logic to the report method to log some extra information or send a notification email:

public function report(Throwable $exception)
{
// Call the parent report method
parent::report($exception);

// Add some custom logic
if ($exception instanceof PaymentFailedException) {
// Log some extra information
Log::info('Payment failed for user ' . Auth::id());

// Send a notification email
Mail::to(Auth::user())->send(new PaymentFailedNotification($exception));
}
}

You can also modify the render method to change how the exception is displayed to the user. For example, you can return a custom JSON response for API requests:

public function render($request, Throwable $exception)
{
// If the request expects JSON
if ($request->expectsJson()) {
// Return a custom JSON response
return response()->json([
'error' => $exception->getMessage(),
'code' => $exception->getCode(),
], $exception->getStatusCode());
}

// Otherwise, call the parent render method
return parent::render($request, $exception);
}

How to register custom exception handlers in Laravel?

Another way to customize exception handling in Laravel is to register custom exception handlers using the Handler class’s register method. This method allows you to define a closure that will be executed when a specific type of exception is thrown.

For example, you can register a custom handler for ValidationException that will redirect the user back to the previous page with the validation errors:

public function register()
{
// Register a custom handler for ValidationException
$this->renderable(function (ValidationException $e, $request) {
// If the request expects JSON
if ($request->expectsJson()) {
// Return a JSON response with the validation errors
return response()->json($e->errors(), $e->status);
}

// Otherwise, redirect back with the validation errors
return redirect()->back()->withInput()->withErrors($e->errors());
});
}

You can also register multiple handlers for different types of exceptions. For example, you can register a custom handler for ModelNotFoundException that will return a 404 response with a custom message:

public function register()
{
// Register a custom handler for ModelNotFoundException
$this->renderable(function (ModelNotFoundException $e, $request) {
// Return a 404 response with a custom message
return response()->view('errors.model', [
'message' => 'The requested model was not found',
], 404);
});
}

Conclusion

In this article, we have learned some tips and tricks on how to handle exceptions in Laravel effectively. We have seen how to throw and catch exceptions manually, how to customize exception handling using the Handler class, and how to register custom exception handlers using the renderable method.

Laravel’s error and exception handling system is one of its most powerful features that makes developing web applications easier and more enjoyable. By mastering this system, you can create robust and user-friendly applications that can handle any unexpected situations gracefully.

--

--

Moumen Alisawe

Software engineer with 6+ years developing mobile and web apps. Passionate about creating seamless user experiences. Let's build something great together.