Be careful when using error reporting services and serverless functions
Tags: ruby, serverless, lambda, monitoring
Published: 2019-08-31 07:13:22

First, a disclaimer: the problem presented by this blog post happened when using AWS Lambda, Honeybadger, and Ruby. If you're using a different cloud provider, error reporting service and/or programming language, this might not be a problem, **which doesn't mean you shouldn't be aware of it**.

That said, let's start.

[Honeybadger](https://www.honeybadger.io) is a popular service for monitoring errors and application uptime like many others. We use it in production for a long time and it's taking care nicely, however, when we started using Honeybadger to report eventual problems in our AWS Lambda functions, a very interesting and unexpected situation happened.

We started to notice that Honeybadger eventually failed to report errors from our lambda functions, which is very tricky because we rely on it to notifies us when something goes wrong. If there are no notifications, there are no problems, right? We have more important things to do rather than watching the logs in Cloudwatch all over the day.

This week I was intentionally provoking errors in one particular lambda function, just to check if Honeybadger would report errors, but it didn't.

According to the Honeybadger documentation ([Architecture Deep-Dive](https://docs.honeybadger.io/lib/ruby/gem-reference/architecture.html)), the `Worker`, which is responsible for pulling `Notice` from the `Queue`, runs in a different thread to not block the execution of your application while reporting errors. This is great, however, it represents a problem when running in serverless functions.

The [AWS Lambda Execution Context](https://docs.aws.amazon.com/lambda/latest/dg/running-lambda-code.html) page says:

> Background processes or callbacks initiated by your Lambda function that did not complete when the function ended resume if AWS Lambda chooses to reuse the execution context. You should make sure any background processes or callbacks in your code are complete before the code exits.

Which means, when your lambda function finishes the execution, the `Worker`, which runs in a different thread, might not have finished sending the error notification.

Fortunately, the solution is simple. However, it took me some time to find it because, until the moment I'm writing this post, it's not available in Honeybadger documentation (yes, I needed to dive into their code).

When using the `Honeybadger.notify` method, make sure to set `sync: true`:

```
Honeybadger.notify(error, sync: true)
```

When using `sync: true`, Honeybadger will send the notification immediately, and not pushing it into the queue to be processed by the worker: https://github.com/honeybadger-io/honeybadger-ruby/blob/master/lib/honeybadger/agent.rb#L161

Alternatively, you can also call `Honeybadger.flush` after calling `Honeybadger.notify` to force Honeybadger to send all the notifications: https://github.com/honeybadger-io/honeybadger-ruby/blob/master/lib/honeybadger/agent.rb#L314

If you want to know more about this matter, take a look at this nice article in DZone: [Multi-Threaded Programming With AWS Lambda](https://dzone.com/articles/multi-threaded-programming-with-aws-lambda)