How to Handle Errors & Exceptions in the Yii Framework

Introduction. In today’s tutorial, I’ll introduce Yii’s error and exception handling and guide you through some introductory scenarios.

How to Handle Errors & Exceptions in the Yii Framework

How to Handle Errors & Exceptions in the Yii Framework

Wondering what Yii is? Check out our Introduction to the Yii Framework and Programming With Yii2 series.

What’s the Difference Between Errors and Exceptions?

Errors are unexpected defects in our code often discovered first by users. They’ll typically break program execution. It’s important not only to break gracefully for the user but to inform the developer of the problem so it can be fixed.

Exceptions are created by the developer when a potentially predictable error condition occurs. In code where an exception might occur, the developer can throw() an exception to a robust error handler.

How Does Yii Manage These?

In Yii, non-fatal PHP errors (e.g. warnings and notices) are routed into catchable exceptions so you can decide how to react and respond to them. You can designate a controller action to process all of these exceptions. And you can customize the display format for errors, e.g. HTML, JSON, XML, etc.

Exceptions and fatal PHP errors can be assessed only in debug mode. In these kinds of development scenarios, Yii can display detailed call stack information and segments of source code (you can see this above in the title image).

Fatal errors are the kind of events that break application execution. These include out of memory, instantiating an object of a class that doesn’t exist, or calling a function that doesn’t exist.

For example:

$t = new Unknownobject();

Let’s get started with some examples of error and exception handling.

Configuring Error and Exception Handling

First, we configure our application in frontend/config/main.php. The errorHandler is defined as a component, as shown below. This example is from my startup series application, Meeting Planner. Notice the errorHandler configuration in components:

<?php
$params = array_merge(
    require(__DIR__ . '/params.php'),
    require(__DIR__ . '/params-local.php')
);
return [
    'id' => 'mp-frontend',
    'name' => 'Meeting Planner',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log','commoncomponentsSiteHelper'],
    'controllerNamespace' => 'frontendcontrollers',
    'catchAll'=> [],
    'components' => [
      'assetManager' => [...],
      ...
      'errorHandler' => [
            'errorAction' => 'site/error',
            'maxSourceLines' => 20,
        ],
        ...
    ],
];

In the above example, errorAction directs the user to my SiteController’s error action.

More broadly, Yii offers a variety of configuration options for errorHandler for redirection and data gathering:

Property Type Description
$callStackItemView string The path of the view file for rendering exceptions and errors call stack element. e.g. ‘@yii/views/errorHandler/callStackItem.php’
$displayVars array List of the PHP predefined variables that should be displayed on the error page. e.g. [‘_GET’, ‘_POST’, ‘_FILES’, ‘_COOKIE’, ‘_SESSION’]
$errorAction string The route (e.g. site/error) to the controller action that will be used to display external errors.
$errorView string The path of the view file for rendering exceptions without call stack information. e.g. ‘@yii/views/errorHandler/error.php’
$exceptionView string The path of the view file for rendering exceptions. e.g. ‘@yii/views/errorHandler/exception.php’
$maxSourceLines integer Maximum number of source code lines to be displayed.
$maxTraceSourceLines integer Maximum number of trace source code lines to be displayed.
$previousExceptionView string The path of the view file for rendering previous exceptions. e.g. ‘@yii/views/errorHandler/previousException.php’

Using errorActions to Direct Execution

Generally, when a user encounters a serious error, we want to redirect them to a friendly, descriptive error page.

That’s what the errorAction in errorHandler does. It redirects to our SiteController’s actionError:

return [
    'components' => [
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
    ]
];

In our SiteController, we define an explicit error action:

namespace appcontrollers;

use Yii;
use yiiwebController;

class SiteController extends Controller
{
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yiiwebErrorAction',
            ],
        ];
    }
}

Here’s a basic error handler (you can read more about these here):

public function actionError()
{
    $exception = Yii::$app->errorHandler->exception;
    if ($exception !== null) {
        return $this->render('error', ['exception' => $exception]);
    }
}

You can also respond differently whether there is an error or whether the page request does not exist in your application:

public function actionError()
    {
        $exception = Yii::$app->errorHandler->exception;
        if ($exception instanceof yiiwebNotFoundHttpException) {
            // all non existing controllers+actions will end up here
            return $this->render('pnf'); // page not found
        } else {
          return $this->render('error', ['exception' => $exception]);
        }
    }

Here’s my current Page Not Found 404 error handler:

How to Handle Errors &amp; Exceptions in the Yii Framework

You could theoretically include a site map of links, suggested pages similar to the page request, a search feature and a contact support link on your error pages. All of these can help the user recover and move on gracefully.

Here’s my current general error page (obviously I have features to add):

How to Handle Errors &amp; Exceptions in the Yii Framework

Catching Exceptions

If we want to monitor a section of code for problems, we can use a PHP try catch block. Below, we’ll experiment by triggering a fatal divide by zero error:

use Yii;
use yiibaseErrorException;

...

    try {
        10/0;
    } catch (ErrorException $e) {
        Yii::warning("Division by zero.");
    }
    
...

The catch response above is to generate a warning for the log. Yii has extensive logging:

  • Yii::trace(): log a message to trace how a piece of code runs. Primarily for development.
  • Yii::info(): log a message that conveys information about the event.
  • Yii::warning(): log a warning message that an unexpected event occurred
  • Yii::error(): log a fatal error for investigation

If, instead of logging an event, you wish to direct the user to the error page we configured earlier, you can throw an exception with the event:

use yiiwebNotFoundHttpException;

throw new NotFoundHttpException();

Here’s an example where we throw an exception with a specific HTTP status code and customized message:

  try {
          10/0;
      } catch (ErrorException $e) {
        throw new yiiwebHttpException(451,
            'Tom McFarlin's humor is often lost on me
                (and lots of people).');
    }

Here’s what that code looks like to the user:

How to Handle Errors &amp; Exceptions in the Yii Framework

About Yii Logging

All errors in Yii are logged depending on how you’ve set them up. You may also be interested in my tutorial about Sentry and Rollbar for logging in Yii:

  • How to Handle Errors &amp; Exceptions in the Yii Framework

    Building Your Startup: Error Logging

    Finding production errors can be difficult without proper error handling or a cloud-based logging service. I tried two. Follow along and learn how logging…

In Closing

I hope you enjoyed our exploration of error and exception handling. Watch for upcoming tutorials in our Programming With Yii2 series as we continue diving into different aspects of the framework.

If you’d like to see a deeper dive in Yii application development, check out our Building Your Startup With PHP series which uses Yii2’s advanced template. It tells the story of programming each step of Meeting Planner. It’s very useful if you want to learn about building applications in Yii from the ground up.

If you’d like to know when the next Yii2 tutorial arrives, follow me @lookahead_io on Twitter or check my instructor page.

Related Links