question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

APM agent (and so app) dies when using the bodyParser plugin in restify application - unhandled exception prevent route completion

See original GitHub issue

Describe the bug When using ES APM Agent in an restify app and the bodyParser Plugin at the same time, the app dies with the first request/an exception is thrown by APM which cannot be handled. APM agent writes his own error wrappedHandler (node_modules/elastic-apm-node/lib/instrumentation/modules/restify.js) but afterwards the request dies.

To Reproduce Steps to reproduce the behavior:

  1. Create a npm project (elastic-apm-node version doesn’t matter - bug exists in 1.x and 2.x)
{
  "name": "apm-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "elastic-apm-node": "^1.14.3",
    "restify": "^7.2.3"
  }
}
  1. Create a simple server
// // Add this to the VERY top of the first file loaded in your app
var apm = require('elastic-apm-node').start({
    serviceName: 'development_apm-test',
  
    // Set custom APM Server URL (default: http://localhost:8200)
    serverUrl: 'http://XXXX:8200',
  })

var restify = require('restify');

function respond(req, res, next) {
  res.send('hello ' + req.params.name);
  next();
}

var server = restify.createServer();

server.use(restify.plugins.jsonBodyParser());

server.get('/hello/:name', respond);
server.head('/hello/:name', respond);

server.listen(8080, function() {
  console.log('%s listening at %s', server.name, server.url);
});
  1. Call the app’s endpoint in the browser…
http://localhost:8080/hello/waldi
  1. See in the console logging error XXXX-XXX-XXX with Elastic APM and the request is dead.
  2. Output in Kibana/ES:
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "filename": "node_modules/elastic-apm-node/lib/instrumentation/modules/restify.js",
  "abs_path": "~/apm-test/node_modules/elastic-apm-node/lib/instrumentation/modules/restify.js",
  "line": {
    "number": 37,
    "context": "        return handler.apply(this, arguments)"
  },
  "function": "wrappedHandler",
  "context": {
    "pre": [
      "          }",
      "        })"
    ],
    "post": [
      "      }",
      "    }"
    ]
  }
},
{
  "exclude_from_grouping": false,
  "library_frame": true,
  "filename": "node_modules/restify/lib/chain.js",
  "abs_path": "~/apm-test/node_modules/restify/lib/chain.js",
  "line": {
    "number": 164,
    "context": "        handler(req, res, next);"
  },
  "function": "call",
  "context": {
    "pre": [
      "    } else if (!hasError && arity < 4) {",
      "        // request-handling middleware"
    ],
    "post": [
      "        return;",
      "    }"
    ]
  }
},
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "filename": "node_modules/restify/lib/chain.js",
  "abs_path": "~/apm-test/node_modules/restify/lib/chain.js",
  "line": {
    "number": 120,
    "context": "        call(handler, err, req, res, self.onceNext ? self._once(next) : next);"
  },
  "function": "next",
  "context": {
    "pre": [
      "",
      "        // call the handler"
    ],
    "post": [
      "    }",
      ""
    ]
  }
},
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "filename": "node_modules/restify/lib/chain.js",
  "abs_path": "~/apm-test/node_modules/restify/lib/chain.js",
  "line": {
    "number": 123,
    "context": "    next();"
  },
  "function": "run",
  "context": {
    "pre": [
      "    }",
      ""
    ],
    "post": [
      "    return;",
      "};"
    ]
  }
},
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "filename": "node_modules/restify/lib/server.js",
  "abs_path": "~/apm-test/node_modules/restify/lib/server.js",
  "line": {
    "number": 1002,
    "context": "    self.useChain.run(req, res, function useChainDone(err) {"
  },
  "function": "_runUse",
  "context": {
    "pre": [
      "    req._timeUseStart = process.hrtime();",
      ""
    ],
    "post": [
      "        // Execution time of a handler with error can be significantly lower",
      "        req._timeUseEnd = process.hrtime();"
    ]
  }
},
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "abs_path": "~/apm-test/node_modules/restify/lib/server.js",
  "filename": "node_modules/restify/lib/server.js",
  "line": {
    "number": 916,
    "context": "    self._runUse(req, res, function afterUse() {"
  },
  "function": "_runRoute",
  "context": {
    "pre": [
      "    self.emit('routed', req, res, req.route);",
      ""
    ],
    "post": [
      "        // DTrace",
      "        if (self.dtrace) {"
    ]
  }
},
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "abs_path": "~/apm-test/node_modules/restify/lib/server.js",
  "filename": "node_modules/restify/lib/server.js",
  "line": {
    "number": 886,
    "context": "    self._runRoute(req, res);"
  },
  "function": "_afterPre",
  "context": {
    "pre": [
      "    }",
      ""
    ],
    "post": [
      "};",
      ""
    ]
  }
},
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "filename": "node_modules/restify/lib/server.js",
  "abs_path": "~/apm-test/node_modules/restify/lib/server.js",
  "line": {
    "number": 854,
    "context": "        self._afterPre(err, req, res);"
  },
  "function": "preChainDone",
  "context": {
    "pre": [
      "        // Execution time of a handler with error can be significantly lower",
      "        req._timePreEnd = process.hrtime();"
    ],
    "post": [
      "    });",
      "};"
    ]
  }
},
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "filename": "timers.js",
  "abs_path": "timers.js",
  "line": {
    "number": 634
  },
  "function": "processImmediate"
},
{
  "library_frame": true,
  "exclude_from_grouping": false,
  "filename": "domain.js",
  "abs_path": "domain.js",
  "line": {
    "number": 120
  },
  "function": "topLevelDomainCallback"
}

Expected behavior App runs normal without beeing influenced or interrupted by APM.

Environment (please complete the following information)

  • OS: OSX 10.14.1; Docker Image node:alpine latest.
  • Node.js version: v10.4.1
  • APM Server version: 6.2.3
  • Agent version: 1.x or 2.x doesn’t matter

How are you starting the agent? (please tick one of the boxes)

  • Calling agent.start() directly (e.g. require('elastic-apm-node').start(...))
  • Requiring elastic-apm-node/start from within the source code
  • Starting node with -r elastic-apm-node/start

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:22 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
waswrongassembledcommented, Dec 10, 2018

@watson works like a charm.

1reaction
gcsabbaghcommented, Dec 7, 2018

@watson you are correct, it was docker volumes shenanigans at play. it works as expected now, thank you!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Plugins API - Restify
This plugin deduplicates extra slashes found in the URL. This can help with malformed URLs that might otherwise get misrouted. Examples. server.
Read more >
How to disable restify.plugin.bodyParser for file uploads
I just changed server.use(restify.plugins.bodyParser()); by server.use(restify.plugins.jsonBodyParser()); and everything is working fine.
Read more >
vocab.txt - Hugging Face
... ##line parent Use Your connection compile however ##pload complete handle ... care apps callback ##thers special Microsoft person bottom ##Exception ...
Read more >
Hih - ALBA.Net
Moradias para venda sao mamede batalha, Menetaskan telur dengan mesin, Newclassic ms204s, Transmorpher walkthrough level 18, Innotab 2 games and apps, ...
Read more >
1cad221de081ea61b34d3b8588...
It assumes a basic knowledge of both JavaScript and building applications using Spring. DWR DWR makes it easy to use of Asynchronous JavaScript...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found