Laravel Error Handling and Logging

Lesson 41 of 50

82%
1. Introduction to Error Handling

Error handling is the process of detecting, managing, and responding to errors that occur in an application. Laravel provides tools to handle exceptions and record useful information about application problems.

Common errors in Laravel include:

  • Database connection errors.
  • Missing database records.
  • Invalid user input.
  • Authentication and authorization errors.
  • Missing files or configuration settings.
  • Unexpected exceptions in application code.

Good error handling helps developers identify problems without exposing sensitive information to users.

Example:

try {
    $result = 10 / 0;
} catch (Throwable $e) {
    echo "An error occurred.";
}

This illustrates the idea of catching an error or exception. In real applications, avoid deliberately dividing by zero; validate inputs and handle expected failures appropriately.

2. Understanding Laravel Debug Mode

Laravel's debug mode controls how much diagnostic information is displayed when an unhandled exception occurs.

In your .env file, local development may use:

APP_ENV=local
APP_DEBUG=true

For production, use:

APP_ENV=production
APP_DEBUG=false

Why is this important?

  • Debug mode helps developers diagnose problems locally.
  • Production debug pages may reveal file paths, queries, or configuration details.
  • Production errors should be logged privately instead of exposing technical details to visitors.

After changing environment settings, clear cached configuration if necessary:

php artisan config:clear
3. Handle Exceptions Using try and catch

PHP's try and catch statements allow you to handle exceptions without immediately terminating the current operation.

Example in a Laravel controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Log;
use Throwable;

class ReportController extends Controller
{
    public function generate()
    {
        try {
            // Perform report generation here.

            return response()->json([
                'message' => 'Report generated successfully.',
            ]);
        } catch (Throwable $e) {
            Log::error('Report generation failed.', [
                'exception' => $e,
            ]);

            return response()->json([
                'message' => 'Unable to generate the report.',
            ], 500);
        }
    }
}

The catch block records diagnostic information and returns a generic error response.

Catch only exceptions you can handle meaningfully. Laravel can automatically handle many uncaught exceptions, so a broad catch is not necessary in every controller method.

4. Log Messages in Laravel

Laravel provides the Log facade to record messages about application activity and errors.

Import the facade:

use Illuminate\Support\Facades\Log;

Example log messages:

Log::debug('Debugging student report.');

Log::info('Student registered successfully.');

Log::notice('Unusual activity detected.');

Log::warning('Student record is missing optional data.');

Log::error('Unable to send email.');

Log::critical('Critical service failure.');

Common logging levels:

  • debug — Detailed diagnostic information.
  • info — Normal application events.
  • notice — Normal but noteworthy events.
  • warning — Conditions that may require attention.
  • error — Errors that need investigation.
  • critical — Serious failures.

Log messages are written according to the configured logging channel and minimum log level.

5. Find and Read Laravel Log Files

With the default single-file logging configuration, Laravel commonly writes application logs to:

storage/logs/laravel.log

The exact location and filename depend on your configured logging channel.

Example of logging additional context:

use Illuminate\Support\Facades\Log;

Log::error('Student payment failed.', [
    'student_id' => 25,
    'payment_reference' => 'PAY-10025',
]);

Context helps developers identify which operation failed without having to guess from a generic message.

Useful troubleshooting steps:

  1. Check the latest entries in the configured log file.
  2. Identify the exception message and stack trace.
  3. Check the referenced controller, model, or service.
  4. Verify database and environment configuration.
  5. Reproduce the issue and test the correction.

Never write passwords, access tokens, or other sensitive personal information into logs.

6. Handle Missing Database Records

Laravel's Eloquent ORM provides findOrFail() to retrieve a record or raise a model-not-found exception if the record does not exist.

Example controller method:

use App\Models\Student;

public function show(string $id)
{
    $student = Student::findOrFail($id);

    return response()->json([
        'data' => $student,
    ]);
}

If the student is not found, Laravel normally returns a 404 response for this request.

If you want to handle the missing record explicitly, you can use find():

public function show(string $id)
{
    $student = Student::find($id);

    if (!$student) {
        return response()->json([
            'message' => 'Student not found.',
        ], 404);
    }

    return response()->json([
        'data' => $student,
    ]);
}

Use an appropriate HTTP status code to describe the outcome of an API request.

7. Customize Exception Handling

Laravel provides centralized exception handling. In modern Laravel applications, much of this configuration is defined in bootstrap/app.php.

You can customize how certain exceptions are reported or rendered. For example, an API may need JSON error responses instead of HTML error pages.

Example JSON response structure:

{
    "message": "The requested student was not found."
}

A controller can also return an explicit error response when the application can handle the condition directly:

return response()->json([
    'message' => 'The requested student was not found.',
], 404);

Keep detailed exception information in private logs and return safe, understandable messages to clients.

Exception configuration differs across Laravel versions. Follow the structure of your installed version instead of copying an older exception-handler example into every project.

8. Error Handling Best Practices
  • Keep APP_DEBUG=false in production.
  • Use appropriate logging levels.
  • Return meaningful HTTP status codes.
  • Do not expose stack traces or database details to users.
  • Validate request data before processing it.
  • Catch exceptions when you can recover or provide a useful response.
  • Protect log files and restrict access to them.
  • Never log passwords, secrets, or access tokens.
  • Monitor recurring failures and fix their root causes.

Remember:

Logging records what happened. Exception handling determines how your application responds to an error. Both are important for maintaining a reliable Laravel application.

9. Practice Assignment

Complete the following practical tasks:

  1. Write an informational log when a student registers.
  2. Write an error log when report generation fails.
  3. Use try and catch in a suitable controller operation.
  4. Use findOrFail() to handle a missing student record.
  5. Return a JSON 404 response for a missing student.
  6. Inspect the configured Laravel log file.
  7. Configure debug mode appropriately for development and production.

Bonus Task:

Create an API endpoint that retrieves a student's payment history. If an unexpected error occurs, log the exception and return a safe JSON error response.

Quick Quiz

1. Which facade is used for logging in Laravel?




2. Which Eloquent method raises an exception when a record is missing?




3. What should APP_DEBUG generally be in production?