Error tracking in PHP and JavaScript

Written by Christophe Limpalair on 11/23/2015

Have you ever deployed code with errors? What about a really bad error that had your co-founder or boss blowing up your phone? At least they told you about it, because there are always those errors that go hours, days, or even weeks, without developers noticing.

I know you have. We all have.

Finding and solving errors is such a big problem that reddit had to roll out their own solution a few years back, as Jeremy Edberg told me in his interview.

Thankfully, you don't have to create your own solution nowadays. There are existing products that do a great job, and we're going to look at a solution that you can install in 5 minutes.


What can you do with error tracking?
(If you're looking for installation instructions, scroll down to the sections about Laravel and JavaScript)

First of all, what can error tracking do and what can't it do?

What it can do:
  • Log and classify errors

  • Alert you when there's an error (Integrating with tools or email)

  • Show what line of code caused the error

  • Show when it first happened, the last time it happened, and how many times it happened

  • And more that I'll expand on further down

What it can't do:
  • It's not a silver bullet. You still need to test your code

  • It can't fix bugs for you. It tells you there are bugs and gives you more insight


What errors do I track? What do I use?
I'm running a Laravel app and logging all exceptions with a product called Rollbar.

As a disclaimer, Rollbar has sponsored the show. This is not a paid article, however. I use it for ScaleYourCode and really believe you can benefit from an error tracking service as well. I've also had requests for testing tutorials. While this isn't exactly a testing tutorial, it is quite relevant.

Here's an example to give a small idea of what we can do with this type of product:

Say a potential sponsor reaches out to us (or in your case, maybe a potential customer/client). There is a form for them to fill out and submit, and I might log that in a database and email it out to my account with a third party email API.

What could possibly go wrong? Well, the database could fail. The email API could return an error. Or both, if you're having a really bad day.

Worst case scenario, I lose trace of this submission and lose business. In my case, this is highly unlikely because I can reduce the risk with other layers of tracking, but I would still have to manually check those logs and I'd rather spend my time on more important tasks.

What's more likely to happen is that I don't receive the email, or some other service fails to record this submission. In any case, I want to know that this failure happened, especially if it's one of my services. It'd be nice to know about third party API failures as well.

This is where an error tracking product steps in. If any of these services return errors, it gets logged, I get notified, and I can view it in my dashboard. A quick glance will reveal which service is at fault. I also have the ability to see the HTTP parameters, including any POST fields.

I could even log certain fields with the application to help debug: (I'll explain further down how to set up
Log
to report to Rollbar)
if ( $send == 'failed' ) {
Log::error('Service_name failed', [
'submission' => [ 'email' => $input['email'], etc.. ]
]);
}


You can pass in any relevant information that could have caused the error. In this case it's highly unlikely to be one of the inputs, but you never know. Anyway, I'm aware something messed up, I can quickly figure out what happened, and I still have the company's information to respond.

I set up a testing scenario where I purposefully swapped my email API key for a fake one. This will return an error from the API, and it will get logged.

Here's the result:

Rollbar example of error messages in dashboard

The first thing we see is a red circle with a white X at the center. This represents an error, and clearly stands out from the item below, which only displays a grey circle with a white question mark (to signal a debug notice). We can quickly glance at the dashboard and see what needs our immediate attention.

To the left of these items, you see a Count column and a 24hr Trend column. The "Test email registration" item has a count of 3 because I tested it 3 total times, with only one of those times where we attempted to send an email.

When I click on the error item, it pulls up another page titled with the error message and populated with this:
Rollbar Traceback error reporting

The Traceback shows us what the app spits out and can be very helpful in debugging. If you link your GitHub account, Rollbar could also link directly to the line of code that caused the exception. I'm sure you can imagine how helpful just this first tab is in debugging your app.

The other tab I'm going to explore with you for this post is the next one over called Occurrences.

This tab gives you more information about the request itself. Clicking on the Timestamp pulls up a separate page which gives you a more readable format as you peak into the HTTP request.

Again, it shows you the stack trace, but below that we also get to look into all kinds of parameters:
HTTP details

I'm only showing you a fraction of what it gives you, but I wanted to point out the fact that it captured the POST field(s). This can be super helpful in determining the root cause.

There are also other tabs like Browser/OS, IP Adresses, Suspect Deploy, and more. Take a look at those to see the useful information they provide.

Here's another use case:

Have you ever been on a website and run into a 404 page? How do you currently find 404 pages? You could use Google Webmaster tools or Google Analytics. I'm sure there are a bunch of free tools out there too, but why manually check when you can automate? And why complicate things with an extra tool? Just log a warning anytime your app catches a 404.

You can easily see the page that triggered it and the referrer.
Log::warning('404');


These are just two of thousands or even millions of use cases. Just think of any time you've hit the refresh button after adding a new feature, and seeing that dreaded stack trace. Sometimes it's really easy to tell what you messed up, but other times it feels like you're going in blind. An error tracking product gives you visibility during development and while in production.


How to get started with Laravel?

You're not going to believe me when I say this is going to take you 5 minutes. But I timed it, and it does only take 5 minutes.

Like many things in Laravel, there's a nice person that created a drop-in integration that we can add with composer. Here's the package.

The instructions there are straight forward, but I'll add them here as well.

Add the package to composer:
composer require jenssegers/rollbar


Add it to your service providers in
config/app.php

'Jenssegers\Rollbar\RollbarServiceProvider'


We then need to add configs in your
config/services.php

'rollbar' => [
'access_token' => 'your-server-key-here',
'level' => 'debug'
]


The default level is 'debug' with this integration. This would be a good setting for development, and you could switch it to error for development. 'Error' would ignore info and debug notices.

That's it! You can now use Rollbar with
Log


Want to log all error handling? Just use the
Log
facade in your
app/Exceptions/Handler.php
report function:
public function report(Exception $e)
{
\Log::error($e);
return parent::report($e);
}


This will automatically report all errors thrown.

If you want to add other debugging logging somewhere in your application, you can easily do it with the
Log
facade we just used.

Log::debug('Registration Submission', [
'user' => [
'email' => $input['email'],
'username' => $input['username'],
'password' => $input['password']
]
]);


It could also be a simple message:
Log::debug('Debug this');


Try it out, and you'll see the info in your dashboard within seconds.


Debugging JavaScript

I'm adding this section because it will be super helpful for a lot of people. Debugging JS can be a major pain for me, and setting this up is really easy just like it was with PHP.

Here is the full guide from Rollbar's documentation for JavaScript.

The code to add is minified and a little lengthy so I'm not adding all of it here, but here's part of it: (Don't just copy/paste this, go to the above link and copy the entire code!)
<script>
var _rollbarConfig = {
accessToken: "POST_CLIENT_ITEM_ACCESS_TOKEN",
captureUncaught: true,
payload: {
environment: "production"
}
};
!function(r){function t(o){if(e
...
</script>


Add this as early on as you can, before any other scripts.

For the accessToken, you can find it in your Project's settings. While in your project dashboard, click on Settings in the top navigation bar. In the left menu, click on Project Access Tokens, and use the
post_client_item
key.

You can test that this is working by navigating to the page where you added the script, opening your inspector, and entering this line in this console:
window.onerror("TestRollbarError: testing window.onerror", window.location.href)


As long as you pasted the entirety of the code and used the correct API key, an error will pop up in your dashboard.

Good, now we can continue. You can use this in a number of ways:

Wrap in try/catch
try {
doSomething();
} catch (e) {
Rollbar.error("Something went wrong", e);
}


Log anything, anywhere you like.
Rollbar.critical("Connection error from remote Payments API");
Rollbar.warning("Connection error from Twitter API");
Rollbar.info("User opened the purchase dialog", {userId: 495});
Rollbar.debug("Purchase dialog finished rendering");


There's a lot more to it. Check out more in the documentation.


Conclusion

Cool, right? I was really excited when I ran across this. Probably because it's going to save me hours in the long-run, but also because it's fun ;).

Keep in mind that I only showed how to implement Rollbar in Laravel and JavaScript. There are far more languages available. This product works with most, if not all, languages. Even in the rare case that the language you use isn't supported, you can plug in their API.

There are also other products out there, but this is the one I use and am familiar with.

Happy tracking!