From 6cb9a3bb29725d5a5116cedcd502996d0b158f67 Mon Sep 17 00:00:00 2001 From: Joe Haines Date: Mon, 1 Jun 2020 14:58:08 +0100 Subject: [PATCH 1/3] fix(plugin-express): fetch request body in onError This fixes an issue where the body may not exist when the request handler runs and so the body will be missing from the error report in the dashboard This can happen because the body may be parsed by middleware that runs after the requestHandler --- packages/plugin-express/src/express.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin-express/src/express.js b/packages/plugin-express/src/express.js index a83e2f3ed2..80c4864571 100644 --- a/packages/plugin-express/src/express.js +++ b/packages/plugin-express/src/express.js @@ -25,10 +25,10 @@ module.exports = { req.bugsnag = requestClient // extract request info and pass it to the relevant bugsnag properties - const { request, metadata } = getRequestAndMetadataFromReq(req) - requestClient.addMetadata('request', metadata) requestClient.addOnError((event) => { + const { metadata, request } = getRequestAndMetadataFromReq(req) event.request = { ...event.request, ...request } + requestClient.addMetadata('request', metadata) }, true) // unhandled errors caused by this request From 954014558f8c7349fe44f44dc609de0d8222f1ec Mon Sep 17 00:00:00 2001 From: Ben Gourley Date: Tue, 2 Jun 2020 12:07:41 +0100 Subject: [PATCH 2/3] test(plugin-express): Add assertions for req.body in request metadata --- test/node/features/express.feature | 13 ++ .../fixtures/express/package-lock.json | 200 ++++++++++++++---- .../features/fixtures/express/package.json | 1 + .../fixtures/express/scenarios/app.js | 6 + .../steps/server_fixture_request_steps.rb | 9 + 5 files changed, 193 insertions(+), 36 deletions(-) create mode 100644 test/node/features/steps/server_fixture_request_steps.rb diff --git a/test/node/features/express.feature b/test/node/features/express.feature index 1bb7952fdc..4d51c14fab 100644 --- a/test/node/features/express.feature +++ b/test/node/features/express.feature @@ -105,3 +105,16 @@ Scenario: a handled error passed to req.bugsnag.notify() And the event "request.url" equals "http://express/handled" And the event "request.httpMethod" equals "GET" And the event "request.clientIp" is not null + +Scenario: adding body to request metadata + When I POST the data "data=in_request_body" to the URL "http://express/bodytest" + And I wait to receive a request + Then the request is valid for the error reporting API version "4" for the "Bugsnag Node" notifier + And the event "unhandled" is true + And the event "severity" equals "error" + And the exception "errorClass" equals "Error" + And the exception "message" equals "request body" + And the exception "type" equals "nodejs" + And the "file" of stack frame 0 equals "scenarios/app.js" + And the event "metaData.request.body.data" equals "in_request_body" + And the event "request.httpMethod" equals "POST" diff --git a/test/node/features/fixtures/express/package-lock.json b/test/node/features/fixtures/express/package-lock.json index 87050d9633..955fe56fca 100644 --- a/test/node/features/fixtures/express/package-lock.json +++ b/test/node/features/fixtures/express/package-lock.json @@ -18,26 +18,77 @@ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "requires": { - "bytes": "3.0.0", + "bytes": "3.1.0", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", - "iconv-lite": "0.4.19", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", "on-finished": "~2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "~1.6.15" + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + } } }, "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, "content-disposition": { "version": "0.5.2", @@ -132,6 +183,69 @@ "type-is": "~1.6.16", "utils-merge": "1.0.1", "vary": "~1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.1", + "http-errors": "~1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "~2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "~1.6.15" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": ">= 1.3.1 < 2" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + } } }, "finalhandler": { @@ -170,9 +284,12 @@ } }, "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } }, "inherits": { "version": "2.0.3", @@ -265,36 +382,37 @@ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" - }, "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "requires": { - "depd": "1.1.1", + "depd": "~1.1.2", "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" } }, "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" } } }, @@ -303,6 +421,11 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "send": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", @@ -344,6 +467,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, "type-is": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", diff --git a/test/node/features/fixtures/express/package.json b/test/node/features/fixtures/express/package.json index 730657763c..3b5197480b 100644 --- a/test/node/features/fixtures/express/package.json +++ b/test/node/features/fixtures/express/package.json @@ -1,6 +1,7 @@ { "name": "bugsnag-test", "dependencies": { + "body-parser": "^1.19.0", "express": "^4.16.3" } } diff --git a/test/node/features/fixtures/express/scenarios/app.js b/test/node/features/fixtures/express/scenarios/app.js index b230458ff6..bf578ad627 100644 --- a/test/node/features/fixtures/express/scenarios/app.js +++ b/test/node/features/fixtures/express/scenarios/app.js @@ -1,6 +1,7 @@ var Bugsnag = require('@bugsnag/node') var bugsnagExpress = require('@bugsnag/plugin-express') var express = require('express') +var bodyParser = require('body-parser') Bugsnag.start({ apiKey: process.env.BUGSNAG_API_KEY, @@ -8,6 +9,7 @@ Bugsnag.start({ notify: process.env.BUGSNAG_NOTIFY_ENDPOINT, sessions: process.env.BUGSNAG_SESSIONS_ENDPOINT }, + autoTrackSessions: false, plugins: [bugsnagExpress] }) @@ -69,6 +71,10 @@ app.get('/handled', function (req, res, next) { res.end('OK') }) +app.post('/bodytest', bodyParser.urlencoded(), function (req, res, next) { + throw new Error('request body') +}) + app.use(middleware.errorHandler) app.listen(80) diff --git a/test/node/features/steps/server_fixture_request_steps.rb b/test/node/features/steps/server_fixture_request_steps.rb new file mode 100644 index 0000000000..834428cffe --- /dev/null +++ b/test/node/features/steps/server_fixture_request_steps.rb @@ -0,0 +1,9 @@ +require 'net/http' + +# Attempts to POST a string of urlencoded data to a server. +# +# @step_input reqbody [String] urlencoded data to send. +# @step_input url [String] The URL to post data to. +When("I POST the data {string} to the URL {string}") do |reqbody, url| + Net::HTTP.post(URI(url), reqbody) +end From 988c9f33b6e3491d0e50a22d9c63e36d84d90fd8 Mon Sep 17 00:00:00 2001 From: Ben Gourley Date: Mon, 15 Jun 2020 16:23:09 +0100 Subject: [PATCH 3/3] chore: Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24e69c5d2c..ed6be67b17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## TBD + +### Fixed +- (plugin-express): Ensure `req.body` is always present in metadata by collecting it at the last possible moment [#872](https://github.com/bugsnag/bugsnag-js/pull/872) ## 7.1.1 (2020-05-26)