Error handling

Currently Yii have a very useful error screen when debug mode is enabled: it shows stack trace and some code snippets where error is possible.

What are you missing at Yii error screen? How can we improve error handling?

Personally I’d like to add PHP fatal errors handling. In Yii 1.1 it can be done the following way:




class MyWebApplication extends CWebApplication

{

     public function __construct($config=null)

     {

         parent::__construct($config);

         register_shutdown_function(array($this, 'shutdown'));

     }


     public function shutdown()

     {

         if (YII_ENABLE_ERROR_HANDLER && ($error = error_get_last())) {

             $this->handleError($error['type'], $error['message'], $error['file'], $error['line']);

             die();

         }

     }

}



btw., maybe worth adding in 1.1.

The error screen is very informative and useful… only problem users can have is when they want to post the stack trace to the forum to request help…

the old error screen had a nice stack trace that could be copy/pasted and posted in the forum post

maybe to add the old stack trace on the end of the new error screen so that users can still just copy/paste it for posting…

IMO the fatal errors should happen only during development and I’m not sure if we can display more info than the standard error text… so the idea to handle it would be just to display it in a current layout… but again… those errors should happen only while developing not during production… so I’m not sure for this…

I like mdomba’s idea to add a simple to copy&paste stack trace. I sometimes have to do remote debugging, too and non-techies have to send a screenshot now, to let me see the stack trace.

Another solution might be a small link on top like "Open text version in new window", to make it very easy to select the raw text of the stack trace.

I like Mike’s suggestion of ‘open text version’ – seems like that would allow us to have the nicely displayed version as well as the copy/paste ability that some are lacking.

With web apps becoming increasingly dynamic, I would like to see a debugger that integrates with the client-side - using HTTP headers to transport log/trace information rather than HTML.

mindplay

Can you elaborate about features of this debugger?

Hmm, I think maybe I was getting the logging feature mixed up with the error-handler.

The error-handler doesn’t pass it’s output through the logging mechanism, does it? (why not?)

The solution for AJAX debugging can be found in Django - you have the log in your console, rather then in a browser page.

With PHP 5.4 standalone web server support this can be implemented in PHP.

Another idea is to convert all errors/warnings/notices into exceptions by default.

Why it’s useful?


mkdir($dir);

The code above can raise warning if it can’t create directory. Of course there are is_dir, is_writable etc. but it’s hard to check for all possible conditions that could lead to an error. Moreover, checking with separate functions isn’t atomic. So if project is under high load there can be a problem:


if(!is_dir($dir)){ // passes, there's no such dir yet

  // another process / thread creates directory

  mkdir($dir); // getting an error

}

else {

  // handle error

}

With exceptions it’s atomic:




try {

  mkdir($dir);

}

catch(PhpError $e)

{

  // handle error

}



Exceptions:

I’d very much like it if you used them. :)

Would be great to have an option of turning them off, but IMO exceptions really beats having to deal with various error handlers - it’s just feels too procedural… Exception handling is the way to go. ;)

I agree with Jacmoe, I would prefer use exception handling where possible.

> checking with separate functions isn’t atomic

This looks like a pretty bad solution for a concurrency task in high load, you know that :)

I would say this is a sample of a bad code.

Converting errors to exceptions adds one general value:

you can place exception processing code where you want, rather then sticking to the error handler function.

The cost is increased complexity - execution may jump through multiple includes and hell knows where an exception gets caught and how processed in a team-developed application. We heard about this from Java world.

Well, I can say that in Java it’s pretty convenient to work with exceptions.

I’ve seen this done with an error-handler before, it’s quite useful - particularly because exceptions come with a stack trace, which makes for more useful error messages.

Code that produces E_WARNING tends to be poorly written, so I would agree that throwing exceptions for trapped errors/warnings is a good approach. E_STRICT could also be thrown, as it’s usually an indication that you’re writing code for an older version of the PHP language.

Notices on the other hand are sometimes just helpful information for the developer - I would not suggest you throw those, but rather I would prefer an option that allows me to pass those to a Logger.

One big issue with handling errors in this way, is the fact that legacy code and third-party libraries frequently produce E_WARNING - short of hacking vendor-supplied libraries, there wouldn’t be much you can do to work around that fact. Unless we have an option to disable throwing for specific classes.

Another thing that custom error-handlers of this type frequently get wrong, is the error-suppression operator - if implemented, this must be supported and work as expected, as it’s an integral part of the language.

It seems like there are so many ways to do this, it’s tempting to make this error-handler highly configurable - but that would be both good and bad, since you would have to “learn”, on every project you work on, how errors are handled for that specific project, and potentially you’ll end up with modules/components that require a particular error-handling configuration, which could cause trouble when attempting to integrate modules/components into an application.

Also keep in mind the risk and learning-curve involved when changing standard PHP behavior. That’s not necessarily a deterrent, when you’re changing things for the better, but it does require a level of awareness or will to learn about differing conditions as compared to vanilla PHP code and/or other frameworks…

I deal with that pain every day in .NET - even in some of the core MS runtimes and official MS-supported libraries.

That said, I prefer this over “silent errors” - warnings/notices may go unnoticed, but an exception you have to deal with. You’re forced to demonstrate in your code that you understand that an edge-case may occur. It’s not a bad thing, necessarily - but does happen too often in .NET, and probably (from what I’ve heard) in Java, too…

Sounds good. And there could be some configuration options to include/exclude error levels (warning, notice, strict etc), just like PHP’s error_reporting.

Yes, a way to work around this is to optionally filter by namespace or class. This way you can choose where to convert to an exception and where not to.

Good idea - I would suggest default behavior as follows: throw for undefined namespaces, but for the global (root) namespace, do not throw by default, since code that doesn’t use namespaces is likely legacy code. All recent codebases/projects (worthy of mention) seem to use namespaces now.