---
title: Troubleshoot message consumers
source: https://docs.newrelic.com/docs/apm/agents/nodejs-agent/troubleshooting/troubleshoot-message-consumers
---

## Problem

Message consumer services have a few differences to HTTP servers that make monitoring them more difficult. This document discusses those limitations and ways to work around them with the New Relic Node.js agent.

Because a message does not necessarily have a reply, it can be hard to determine the end of a transaction. If New Relic's Node.js agent cannot determine when a message consumer will be done, it will immediately end the transaction. Follow these troubleshooting tips depending on your application.

## Solution

The solution to this issue depends on whether you are using callbacks or promises:

### Callbacks

When using a callback-based messaging API such as `amqplib`'s `callback_api`, there is no easy way to determine when your consumer is done. Here is an example.

**Callback problem**

In this example, all the transactions created for this service will be immediately ended and not show any of the work done by `doWorkWithMessage`.

````js
const newrelic = require('newrelic');
const amqp = require('amqplib/callback_api');

// Connect, make a channel, and assert required queues...

channel.consume('my.queue', (msg) => {
  doWorkWithMessage(msg, (err) => {
    if (err) {
      logger.error(err);
      channel.reject(msg, true); // Requeue message on failure.
    }
  });
}, { noAck: true });
```

In order to properly time the transaction, you need to get the transaction and end it manually, as shown in the following solution.

````

**Solution**

To properly time the transaction, get the transaction and end it manually. Modify the consumer to this:

````js
channel.consume('my.queue', (msg) => {
  var transaction = newrelic.getTransaction();

  doWorkWithMessage(msg, (err) => {
    if (err) {
      logger.error(err);
      channel.reject(msg, true); // Requeue message on failure.
    }

    transaction.end();
  });
}, { noAck: true });
```

````

### Promises

For promise-based servers, the message consumer simply needs to return a promise. When that promise resolves or rejects, the transaction will be ended. Here is an example:

**Promise problem**

In this example, `doWorkWithMessage` returns a promise:

````js
const newrelic = require('newrelic');
const amqp = require('amqplib');

// Connect, make a channel, and assert required queues...

channel.consume('my.queue', (msg) => {
  doWorkWithMessage(msg).catch((err) => {
    if (err) {
      logger.error(err);
      channel.reject(msg, true); // Requeue message on failure.
    }
  });
}, { noAck: true });
```

````

**Solution**

To get correct timing, return the end of the chain by modifying the code to:

````js
channel.consume('my.queue', (msg) => {
  return doWorkWithMessage(msg).catch((err) => {
    if (err) {
      logger.error(err);
      channel.reject(msg, true); // Requeue message on failure.
    }
  });
}, { noAck: true });
```

````
