Crash Handling

I have often heard it said that Java is a translator – it translates XML files into stack dumps.

The ever present stack dump in many Java programs is due to one fault.  Incorrect or insufficient fallback exception handling meaning that the default process to handle stack dumps is taken – just producing a stack trace.  This isn’t helpful for the end customer because he or she has no idea what that stack trace means, and it isn’t helpful for the development or support teams because they don’t have a permanent record of that stack trace.

Java programs aren’t alone in having this problem and I have seen stack traces produced on many PHP, ASP.NET and other web sites.

What is the correct way to handle this situation?


Frameworks and Foundation Classes

If you’re developing a modern application then it’s probably based on a framework or set of foundation classes.  For example in PHP, Laravel is one of the most common frameworks in use today.  Similarly, Java applications are often built on a framework such as Struts or Play or Tapestry or similar.

Each of these frameworks has a “default” exception handler.  For example in the Laravel documentation we find this mention:

All exceptions are handled by the App\Exceptions\Handler class. This class contains two methods: report and render. We'll examine each of these methods in detail. The report method is used to log exceptions or send them to an external service like Bugsnag or Sentry.

(Ref: https://laravel.com/docs/5.3/errors)

So within our application we have the ability to build a Handler class that will handle every type of exception that the application itself can’t handle internally.  This is what we call a “fallback” exception handler.


Fallback Exception Handlers

So what should we do in this fallback exception handler to prevent ugly stack traces?  Firstly there are some points to remember:

  • The first thing to assume is that everything on your system is broken.  For example it may be the case that you have fallen back to the fallback exception handler because it was impossible to connect to the database, or because the file system has errors.  Assume that there is nothing that we can do without calling for expert help.
  • It’s also safe to assume that you can’t do your normal error logging.  Perhaps there is a file system error or permissions error that stops you writing to your normal log file.  Despite the advice of the Laravel document writers, writing to an external log service such as LogEntries or BugSnag might not work either – because the system may have lost its network connection.  So we have to have a special fallback error logger.


Report The Error

However we need to report the error somewhere, and one common place to do this is syslog. This is a service that runs on most systems that can handle this type of logging, and is usually monitored by some service looking for problems.  Here is an example of some code (using the Monolog framework) that writes to syslog:

$log       = new Logger('myapp');
$syslog    = new SyslogHandler('myapp');
$formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%");

$backtrace = $this->jTraceEx($e);


Note that we don’t use the normal Laravel Log settings, we create a completely new Monolog\Logger object and tie that to syslog, and then we use that.  Remember above where I mentioned that you can’t use your normal logging methods – your log file might be broken.

For an implementation of jTraceEx you can take a look at this useful article:



Render The Error

So now we have reported our bug, the next thing to do is to render it.  For most purposes at this point you just need to display a 503 error page.  The one that I prefer comes from the internet, and of course it contains a cat:


Of course this is just an example – the render method might choose to redirect the customer to a “status” page or blog where you can keep customers informed of efforts you are doing to bring your web site back into operation.