Catching calls to undefined methods in PHP - is it a good idea?
16 Aug 2012Two years ago we built a small class for easier logging and reporting of errors inside our applications by using set_error_handler(). We built it cause:
1) In development mode error display can cause problems
We found ourselves in some situations where PHP notices would be shown inside javascript or hidden elements and it was giving us whole bunch of problems. By using our custom error handler we are able to show errors on the bottom of the page.
2) Staging server reporting
On staging servers we needed fast notifications of any errors so we implemented emailing of all errors to developers which enabled us to react much faster when something goes wrong.
3) Production server reporting
On some smaller productions we have enabled email notifications but on larger ones that was not an option so we decided to log those errors into files which we then can easily pull home. Yes Apache can do this for us too but we needed more information on each error.
If you have any experience with set_error_handler() function then you know that it can not catch fatal errors. There is also a solution for catching them with usage of register_shutdown_function() and I will be testing this implementation very soon (not implemented yet).
But what if we can transform some of those fatal errors into exceptions? We already have a lot of catch blocks prepared and although register_shutdown_function() will give us a report about error, it will show user a broken page instead of a nice 500 Server error custom page. Also maybe that fatal error would occur in some part of process that we already have covered with catch blocks and rest of the page would be shown normally. One of most often fatal errors I proudly produce is a call to undefined method in class that was injected as a dependency.
So my idea is to throw exception in __call magic method and those fatal errors will be transformed into something I can work with. Now my main worry is why PHP is not behaving like that already? Am I missing/forgetting something?
Suggestions and comments are welcomed!