Skip to content

Commit 35e3f1f

Browse files
boneskulltargos
authored andcommitted
report: modify getReport() to return an Object
It's likely that anyone using `process.report.getReport()` will be processing the return value thereafter (e.g., filtering fields or redacting secrets). This change eliminates boilerplate by calling `JSON.parse()` on the return value. Also modified the `validateContent()` and `validate()` test helpers in `test/common/report.js` to be somewhat more obvious and helpful. Of note, a report failing validation will now be easier (though still not _easy_) to read when prepended to the stack trace. - Refs: nodejs/diagnostics#315 PR-URL: #28630 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent ebc3876 commit 35e3f1f

File tree

7 files changed

+44
-26
lines changed

7 files changed

+44
-26
lines changed

doc/api/process.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -1726,14 +1726,19 @@ added: v11.8.0
17261726
-->
17271727

17281728
* `err` {Error} A custom error used for reporting the JavaScript stack.
1729-
* Returns: {string}
1729+
* Returns: {Object}
17301730

1731-
Returns a JSON-formatted diagnostic report for the running process. The report's
1732-
JavaScript stack trace is taken from `err`, if present.
1731+
Returns a JavaScript Object representation of a diagnostic report for the
1732+
running process. The report's JavaScript stack trace is taken from `err`, if
1733+
present.
17331734

17341735
```js
17351736
const data = process.report.getReport();
1736-
console.log(data);
1737+
console.log(data.header.nodeJsVersion);
1738+
1739+
// Similar to process.report.writeReport()
1740+
const fs = require('fs');
1741+
fs.writeFileSync(util.inspect(data), 'my-report.log', 'utf8');
17371742
```
17381743

17391744
Additional documentation is available in the [report documentation][].

doc/api/report.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -463,20 +463,23 @@ try {
463463
// Any other code
464464
```
465465

466-
The content of the diagnostic report can be returned as a JSON-compatible object
466+
The content of the diagnostic report can be returned as a JavaScript Object
467467
via an API call from a JavaScript application:
468468

469469
```js
470470
const report = process.report.getReport();
471-
console.log(report);
471+
console.log(typeof report === 'object'); // true
472+
473+
// Similar to process.report.writeReport() output
474+
console.log(JSON.stringify(report, null, 2));
472475
```
473476

474477
This function takes an optional additional argument `err` - an `Error` object
475478
that will be used as the context for the JavaScript stack printed in the report.
476479

477480
```js
478481
const report = process.report.getReport(new Error('custom error'));
479-
console.log(report);
482+
console.log(typeof report === 'object'); // true
480483
```
481484

482485
The API versions are useful when inspecting the runtime state from within
@@ -498,7 +501,7 @@ Node.js report completed
498501
>
499502
```
500503

501-
When a report is triggered, start and end messages are issued to stderr
504+
When a report is written, start and end messages are issued to stderr
502505
and the filename of the report is returned to the caller. The default filename
503506
includes the date, time, PID and a sequence number. The sequence number helps
504507
in associating the report dump with the runtime state if generated multiple

lib/internal/process/report.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
} = require('internal/errors').codes;
66
const { validateSignalName, validateString } = require('internal/validators');
77
const nr = internalBinding('report');
8+
const { JSON } = primordials;
89
const report = {
910
writeReport(file, err) {
1011
if (typeof file === 'object' && file !== null) {
@@ -26,7 +27,7 @@ const report = {
2627
else if (err === null || typeof err !== 'object')
2728
throw new ERR_INVALID_ARG_TYPE('err', 'Object', err);
2829

29-
return nr.getReport(err.stack);
30+
return JSON.parse(nr.getReport(err.stack));
3031
},
3132
get directory() {
3233
return nr.getDirectory();

test/addons/worker-addon/test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ switch (process.argv[2]) {
3131
}
3232

3333
// Use process.report to figure out if we might be running under musl libc.
34-
const glibc = JSON.parse(process.report.getReport()).header.glibcVersionRuntime;
34+
const glibc = process.report.getReport().header.glibcVersionRuntime;
3535
assert(typeof glibc === 'string' || glibc === undefined, glibc);
3636

3737
const libcMayBeMusl = common.isLinux && glibc === undefined;

test/common/README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -859,19 +859,20 @@ functionality.
859859
Returns an array of diagnotic report file names found in `dir`. The files should
860860
have been generated by a process whose PID matches `pid`.
861861

862-
### validate(report)
862+
### validate(filepath)
863863

864-
* `report` [&lt;string>] Diagnostic report file name to validate.
864+
* `filepath` [&lt;string>] Diagnostic report filepath to validate.
865865

866866
Validates the schema of a diagnostic report file whose path is specified in
867-
`report`. If the report fails validation, an exception is thrown.
867+
`filepath`. If the report fails validation, an exception is thrown.
868868

869-
### validateContent(data)
869+
### validateContent(report)
870870

871-
* `data` [&lt;string>] Contents of a diagnostic report file.
871+
* `report` [&lt;Object|string>] JSON contents of a diagnostic report file, the
872+
parsed Object thereof, or the result of `process.report.getReport()`.
872873

873874
Validates the schema of a diagnostic report whose content is specified in
874-
`data`. If the report fails validation, an exception is thrown.
875+
`report`. If the report fails validation, an exception is thrown.
875876

876877
## tick Module
877878

test/common/report.js

+17-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const assert = require('assert');
44
const fs = require('fs');
55
const os = require('os');
66
const path = require('path');
7+
const util = require('util');
78

89
function findReports(pid, dir) {
910
// Default filenames are of the form
@@ -21,24 +22,31 @@ function findReports(pid, dir) {
2122
return results;
2223
}
2324

24-
function validate(report) {
25-
const data = fs.readFileSync(report, 'utf8');
26-
27-
validateContent(data);
25+
function validate(filepath) {
26+
validateContent(JSON.parse(fs.readFileSync(filepath, 'utf8')));
2827
}
2928

30-
function validateContent(data) {
29+
function validateContent(report) {
30+
if (typeof report === 'string') {
31+
try {
32+
report = JSON.parse(report);
33+
} catch {
34+
throw new TypeError(
35+
'validateContent() expects a JSON string or JavaScript Object');
36+
}
37+
}
3138
try {
32-
_validateContent(data);
39+
_validateContent(report);
3340
} catch (err) {
34-
err.stack += `\n------\nFailing Report:\n${data}`;
41+
try {
42+
err.stack += util.format('\n------\nFailing Report:\n%O', report);
43+
} catch {}
3544
throw err;
3645
}
3746
}
3847

39-
function _validateContent(data) {
48+
function _validateContent(report) {
4049
const isWindows = process.platform === 'win32';
41-
const report = JSON.parse(data);
4250

4351
// Verify that all sections are present as own properties of the report.
4452
const sections = ['header', 'javascriptStack', 'nativeStack',

test/report/test-report-uv-handles.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ if (process.argv[2] === 'child') {
4343
const server = http.createServer((req, res) => {
4444
req.on('end', () => {
4545
// Generate the report while the connection is active.
46-
console.log(process.report.getReport());
46+
console.log(JSON.stringify(process.report.getReport(), null, 2));
4747
child_process.kill();
4848

4949
res.writeHead(200, { 'Content-Type': 'text/plain' });

0 commit comments

Comments
 (0)