Add debug logging to BaseService and BaseJsonService (#1867)
Invoke this using `npm run test:services:trace`.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
'use strict'
|
||||
|
||||
const config = require('./test-config')
|
||||
const serverConfig = require('./server-config')
|
||||
|
||||
let startCalled = false
|
||||
|
||||
@@ -31,13 +32,13 @@ function start() {
|
||||
}
|
||||
startCalled = true
|
||||
|
||||
const originalArgv = process.argv
|
||||
// Modifying argv during import is a bit dirty, but it works, and avoids
|
||||
// making bigger changes to server.js.
|
||||
process.argv = ['', '', config.port, 'localhost']
|
||||
// Modifying config is a bit dirty, but it works, and avoids making bigger
|
||||
// changes to server.js.
|
||||
serverConfig.bind = {
|
||||
host: 'localhost',
|
||||
port: config.port,
|
||||
}
|
||||
const server = require('../server')
|
||||
|
||||
process.argv = originalArgv
|
||||
return server
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ const config = {
|
||||
intervalSeconds: process.env.GITHUB_DEBUG_INTERVAL_SECONDS || 300,
|
||||
},
|
||||
},
|
||||
trace: envFlag(process.env.TRACE_SERVICES),
|
||||
},
|
||||
font: {
|
||||
path: process.env.FONT_PATH || defaults.font.path,
|
||||
|
||||
232
package-lock.json
generated
232
package-lock.json
generated
@@ -378,8 +378,7 @@
|
||||
"acorn": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
|
||||
"integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=",
|
||||
"optional": true
|
||||
"integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
|
||||
},
|
||||
"acorn-dynamic-import": {
|
||||
"version": "2.0.2",
|
||||
@@ -756,6 +755,27 @@
|
||||
"chalk": "^1.1.3",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^3.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-core": {
|
||||
@@ -2237,6 +2257,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"camelo": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/camelo/-/camelo-1.1.11.tgz",
|
||||
"integrity": "sha512-kYyJyTKwCcKXtWMNqHogVBgQMRArxK0sLcPaMgDteo4vHr5vRytzBZt6n2T81RrQIU9FPi4MW8X+snzMDQqH0w==",
|
||||
"requires": {
|
||||
"regex-escape": "^3.3.0",
|
||||
"uc-first-array": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"camp": {
|
||||
"version": "17.2.1",
|
||||
"resolved": "https://registry.npmjs.org/camp/-/camp-17.2.1.tgz",
|
||||
@@ -2334,16 +2363,23 @@
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
|
||||
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"chardet": {
|
||||
@@ -2491,8 +2527,7 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@@ -2513,14 +2548,12 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -2535,20 +2568,17 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@@ -2665,8 +2695,7 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@@ -2678,7 +2707,6 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@@ -2693,7 +2721,6 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@@ -2701,14 +2728,12 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -2727,7 +2752,6 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@@ -2808,8 +2832,7 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@@ -2821,7 +2844,6 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@@ -2907,8 +2929,7 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@@ -2944,7 +2965,6 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@@ -2964,7 +2984,6 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@@ -3008,14 +3027,12 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3239,7 +3256,6 @@
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
|
||||
"integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "^1.1.1"
|
||||
}
|
||||
@@ -3247,8 +3263,7 @@
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.1.2",
|
||||
@@ -3725,8 +3740,7 @@
|
||||
"cssom": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
|
||||
"integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=",
|
||||
"optional": true
|
||||
"integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs="
|
||||
},
|
||||
"cssstyle": {
|
||||
"version": "0.2.37",
|
||||
@@ -4300,6 +4314,22 @@
|
||||
"integrity": "sha1-WUjLKG8uSO3DslGnz8H3iDOW1lw=",
|
||||
"dev": true
|
||||
},
|
||||
"emojic": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/emojic/-/emojic-1.1.14.tgz",
|
||||
"integrity": "sha512-n6yEaHU9GB6AfHTDAvV/263Ds+nIvboyiYYrAOuZox64RP6AlXPW1jbLsT3cBX+8hRVc7IV3P59ODPr2bC0OJA==",
|
||||
"requires": {
|
||||
"camelo": "^1.0.0",
|
||||
"emojilib": "^2.0.2",
|
||||
"iterate-object": "^1.2.0",
|
||||
"r-json": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"emojilib": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.3.0.tgz",
|
||||
"integrity": "sha512-gDrDiITC7W5lvXTtUmk0k9soizsjfY9Wqr2GWsEMX7+cKChoxLt3RnT8zW32BvN1SFDQbi7+D5/+HNu/R+qvKA=="
|
||||
},
|
||||
"emojis-list": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
|
||||
@@ -5655,6 +5685,27 @@
|
||||
"chalk": "^1.1.3",
|
||||
"error-stack-parser": "^2.0.0",
|
||||
"string-length": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"from2": {
|
||||
@@ -6853,6 +6904,11 @@
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"iterate-object": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.2.tgz",
|
||||
"integrity": "sha1-JOwVr/pdADnog5aVohwsrh9Ftms="
|
||||
},
|
||||
"jison": {
|
||||
"version": "0.4.13",
|
||||
"resolved": "https://registry.npmjs.org/jison/-/jison-0.4.13.tgz",
|
||||
@@ -8778,7 +8834,6 @@
|
||||
"version": "0.1.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2",
|
||||
"longest": "^1.0.1",
|
||||
@@ -9809,8 +9864,7 @@
|
||||
"longest": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.3.1",
|
||||
@@ -11765,6 +11819,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"r-json": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/r-json/-/r-json-1.2.8.tgz",
|
||||
"integrity": "sha1-dEBWDMHt8AudjZT6MLytfd6U6uI="
|
||||
},
|
||||
"ramda": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz",
|
||||
@@ -12153,6 +12212,11 @@
|
||||
"private": "^0.1.6"
|
||||
}
|
||||
},
|
||||
"regex-escape": {
|
||||
"version": "3.4.8",
|
||||
"resolved": "https://registry.npmjs.org/regex-escape/-/regex-escape-3.4.8.tgz",
|
||||
"integrity": "sha512-DG0VFPTDwfl+XsuVaM/0RmGJvCpZNB9UG/limzbev50XQ44G4mbOG+0Eh5M7Al9JB68NbP7YeY1KhDzpnX7qSw=="
|
||||
},
|
||||
"regex-not": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
||||
@@ -13618,10 +13682,19 @@
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-hyperlinks": {
|
||||
"version": "1.0.1",
|
||||
@@ -14121,6 +14194,19 @@
|
||||
"integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==",
|
||||
"dev": true
|
||||
},
|
||||
"uc-first-array": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/uc-first-array/-/uc-first-array-1.1.8.tgz",
|
||||
"integrity": "sha512-LTAnb8G/BxmXyBqiUxRhlbYt+IPCCpAOJJsC3xp5cwtXZKdtBfBxAMWRJlNzknM+Gpw3DRD2K3sQ64srroRf3w==",
|
||||
"requires": {
|
||||
"ucfirst": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"ucfirst": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ucfirst/-/ucfirst-1.0.0.tgz",
|
||||
"integrity": "sha1-ThBbZEjQXiZOzsQ14LkZNjxfLy8="
|
||||
},
|
||||
"uglify-es": {
|
||||
"version": "3.3.9",
|
||||
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
|
||||
@@ -14496,6 +14582,27 @@
|
||||
"requires": {
|
||||
"chalk": "^1.1.1",
|
||||
"object-assign": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"verror": {
|
||||
@@ -14892,6 +14999,19 @@
|
||||
"moment": "^2.11.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
@@ -14906,6 +15026,12 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"camp": "~17.2.1",
|
||||
"chalk": "^2.4.1",
|
||||
"chrome-web-store-item-property": "~1.1.2",
|
||||
"dot": "~1.1.2",
|
||||
"emojic": "^1.1.14",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"glob": "^7.1.1",
|
||||
"gm": "^1.23.0",
|
||||
@@ -69,6 +71,7 @@
|
||||
"test:js:server": "HANDLE_INTERNAL_ERRORS=false mocha \"*.spec.js\" \"lib/**/*.spec.js\" \"services/**/*.spec.js\"",
|
||||
"test:integration": "mocha \"services/**/*.integration.js\"",
|
||||
"test:services": "HANDLE_INTERNAL_ERRORS=false mocha --delay lib/service-test-runner/cli.js",
|
||||
"test:services:trace": "TRACE_SERVICES=true npm run test:services -- $*",
|
||||
"test:services:pr:prepare": "node lib/service-test-runner/pull-request-services-cli.js > pull-request-services.log",
|
||||
"test:services:pr:run": "HANDLE_INTERNAL_ERRORS=false mocha --delay lib/service-test-runner/cli.js --stdin < pull-request-services.log",
|
||||
"test:services:pr": "npm run test:services:pr:prepare && npm run test:services:pr:run",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
// See available emoji at http://emoji.muan.co/
|
||||
const emojic = require('emojic')
|
||||
const chalk = require('chalk')
|
||||
const { NotFound, InvalidResponse, Inaccessible } = require('./errors')
|
||||
const queryString = require('query-string')
|
||||
const {
|
||||
@@ -10,6 +13,14 @@ const {
|
||||
setBadgeColor,
|
||||
} = require('../lib/badge-data')
|
||||
const { checkErrorResponse, asJson } = require('../lib/error-helper')
|
||||
// Config is loaded globally but it would be better to inject it. To do that,
|
||||
// there needs to be one instance of the service created at registration time,
|
||||
// which gets the config injected into it, instead of one instance per request.
|
||||
// That way most of the current static methods could become instance methods,
|
||||
// thereby gaining access to the injected config.
|
||||
const {
|
||||
services: { trace: enableTraceLogging },
|
||||
} = require('../lib/server-config')
|
||||
|
||||
class BaseService {
|
||||
constructor({ sendAndCacheRequest }, { handleInternalErrors }) {
|
||||
@@ -141,10 +152,20 @@ class BaseService {
|
||||
}
|
||||
|
||||
async invokeHandler(namedParams, queryParams) {
|
||||
const logTrace = (...args) => this.constructor.logTrace(...args)
|
||||
logTrace(
|
||||
'inbound',
|
||||
emojic.womanCook,
|
||||
'Service class',
|
||||
this.constructor.name
|
||||
)
|
||||
logTrace('inbound', emojic.ticket, 'Named params', namedParams)
|
||||
logTrace('inbound', emojic.crayon, 'Query params', queryParams)
|
||||
try {
|
||||
return await this.handle(namedParams, queryParams)
|
||||
} catch (error) {
|
||||
if (error instanceof NotFound) {
|
||||
logTrace('outbound', emojic.noGoodWoman, 'Handled error', error)
|
||||
return {
|
||||
message: error.prettyMessage,
|
||||
color: 'red',
|
||||
@@ -153,18 +174,36 @@ class BaseService {
|
||||
error instanceof InvalidResponse ||
|
||||
error instanceof Inaccessible
|
||||
) {
|
||||
logTrace('outbound', emojic.noGoodWoman, 'Handled error', error)
|
||||
return {
|
||||
message: error.prettyMessage,
|
||||
color: 'lightgray',
|
||||
}
|
||||
} else if (this._handleInternalErrors) {
|
||||
console.log(error)
|
||||
if (
|
||||
!logTrace(
|
||||
'unhandledError',
|
||||
emojic.boom,
|
||||
'Unhandled internal error',
|
||||
error
|
||||
)
|
||||
) {
|
||||
// This is where we end up if an unhandled exception is thrown in
|
||||
// production. Send the error to the logs.
|
||||
console.log(error)
|
||||
}
|
||||
return {
|
||||
label: 'shields',
|
||||
message: 'internal error',
|
||||
color: 'lightgray',
|
||||
}
|
||||
} else {
|
||||
logTrace(
|
||||
'unhandledError',
|
||||
emojic.boom,
|
||||
'Unhandled internal error',
|
||||
error
|
||||
)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
@@ -232,6 +271,7 @@ class BaseService {
|
||||
namedParams,
|
||||
queryParams
|
||||
)
|
||||
this.logTrace('outbound', emojic.shield, 'Service data', serviceData)
|
||||
const badgeData = this._makeBadgeData(queryParams, serviceData)
|
||||
|
||||
// Assumes the final capture group is the extension
|
||||
@@ -241,6 +281,31 @@ class BaseService {
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
static _formatLabelForStage(stage, label) {
|
||||
const colorFn = {
|
||||
inbound: chalk.black.bgBlue,
|
||||
fetch: chalk.black.bgYellow,
|
||||
validate: chalk.black.bgGreen,
|
||||
unhandledError: chalk.white.bgRed,
|
||||
outbound: chalk.black.bgBlue,
|
||||
}[stage]
|
||||
return colorFn(` ${label} `)
|
||||
}
|
||||
|
||||
static logTrace(stage, symbol, label, ...content) {
|
||||
if (enableTraceLogging) {
|
||||
console.log(
|
||||
this._formatLabelForStage(stage, label),
|
||||
symbol,
|
||||
'\n',
|
||||
...content
|
||||
)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BaseJsonService extends BaseService {
|
||||
@@ -250,29 +315,47 @@ class BaseJsonService extends BaseService {
|
||||
stripUnknown: true,
|
||||
})
|
||||
if (error) {
|
||||
this.logTrace(
|
||||
'error',
|
||||
emojic.womanShrugging,
|
||||
'Response did not match schema',
|
||||
error.message
|
||||
)
|
||||
throw new InvalidResponse({
|
||||
prettyMessage: 'invalid json response',
|
||||
underlyingError: error,
|
||||
})
|
||||
} else {
|
||||
this.logTrace('validate', emojic.bathtub, 'JSON after validation', value)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
async _requestJson({ schema, url, options = {}, notFoundMessage }) {
|
||||
const logTrace = (...args) => this.constructor.logTrace('fetch', ...args)
|
||||
if (!schema || !schema.isJoi) {
|
||||
throw Error('A Joi schema is required')
|
||||
}
|
||||
return this._sendAndCacheRequest(url, {
|
||||
const mergedOptions = {
|
||||
...{ headers: { Accept: 'application/json' } },
|
||||
...options,
|
||||
})
|
||||
}
|
||||
logTrace(emojic.bowAndArrow, 'Request', url, '\n', mergedOptions)
|
||||
return this._sendAndCacheRequest(url, mergedOptions)
|
||||
.then(({ res, buffer }) => {
|
||||
logTrace(emojic.dart, 'Response status code', res.statusCode)
|
||||
return { res, buffer }
|
||||
})
|
||||
.then(
|
||||
checkErrorResponse.asPromise(
|
||||
notFoundMessage ? { notFoundMessage: notFoundMessage } : undefined
|
||||
)
|
||||
)
|
||||
.then(asJson)
|
||||
.then(json => {
|
||||
logTrace(emojic.dart, 'Response JSON (before validation)', json)
|
||||
return json
|
||||
})
|
||||
.then(json => this.constructor._validate(json, schema))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,48 @@ describe('BaseService', () => {
|
||||
expect(serviceData).to.deep.equal({ message: 'Hello bar.bar.bar!' })
|
||||
})
|
||||
|
||||
describe('Logging', function() {
|
||||
let sandbox
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.createSandbox()
|
||||
})
|
||||
afterEach(function() {
|
||||
sandbox.restore()
|
||||
})
|
||||
beforeEach(function() {
|
||||
sinon.stub(DummyService, 'logTrace')
|
||||
})
|
||||
it('Invokes the logger as expected', async function() {
|
||||
const serviceInstance = new DummyService({}, defaultConfig)
|
||||
await serviceInstance.invokeHandler(
|
||||
{
|
||||
namedParamA: 'bar.bar.bar',
|
||||
},
|
||||
{ queryParamA: '!' }
|
||||
)
|
||||
expect(DummyService.logTrace).to.be.calledWithMatch(
|
||||
'inbound',
|
||||
sinon.match.string,
|
||||
'Service class',
|
||||
'DummyService'
|
||||
)
|
||||
expect(DummyService.logTrace).to.be.calledWith(
|
||||
'inbound',
|
||||
sinon.match.string,
|
||||
'Named params',
|
||||
{
|
||||
namedParamA: 'bar.bar.bar',
|
||||
}
|
||||
)
|
||||
expect(DummyService.logTrace).to.be.calledWith(
|
||||
'inbound',
|
||||
sinon.match.string,
|
||||
'Query params',
|
||||
{ queryParamA: '!' }
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Error handling', function() {
|
||||
it('Handles internal errors', async function() {
|
||||
const serviceInstance = new DummyService(
|
||||
|
||||
Reference in New Issue
Block a user