mirror of
https://github.com/directus/directus.git
synced 2026-01-22 18:37:55 -05:00
Fix parsing of Error objects when redacting (#18777)
* Fix parsing of Error objects when redacting * Create perfect-ducks-add.md * Move errorReplacer into redact util * Use unknown instead of any Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch> --------- Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
This commit is contained in:
5
.changeset/perfect-ducks-add.md
Normal file
5
.changeset/perfect-ducks-add.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@directus/api": patch
|
||||
---
|
||||
|
||||
Fixed parsing of Error objects when redacting
|
||||
@@ -1,7 +1,7 @@
|
||||
import { REDACTED_TEXT } from '@directus/constants';
|
||||
import { merge } from 'lodash-es';
|
||||
import { expect, test } from 'vitest';
|
||||
import { redact } from './redact.js';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
import { errorReplacer, redact } from './redact.js';
|
||||
|
||||
const input = {
|
||||
$trigger: {
|
||||
@@ -142,3 +142,69 @@ test('should support multiple paths', () => {
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
describe('errorReplacer tests', () => {
|
||||
test('Returns parsed error object', () => {
|
||||
const errorMessage = 'Error Message';
|
||||
const errorCause = 'Error Cause';
|
||||
const result = errorReplacer('', new Error(errorMessage, { cause: errorCause }));
|
||||
expect(result.name).toBe('Error');
|
||||
expect(result.message).toBe(errorMessage);
|
||||
expect(result.stack).toBeDefined();
|
||||
expect(result.cause).toBe(errorCause);
|
||||
});
|
||||
|
||||
test('Returns other types as is', () => {
|
||||
const values = [
|
||||
undefined,
|
||||
null,
|
||||
0,
|
||||
1,
|
||||
true,
|
||||
false,
|
||||
'',
|
||||
'abc',
|
||||
[],
|
||||
['123'],
|
||||
{},
|
||||
{ abc: '123' },
|
||||
() => {
|
||||
// empty
|
||||
},
|
||||
];
|
||||
|
||||
for (const value of values) {
|
||||
expect(errorReplacer('', value)).toBe(value);
|
||||
}
|
||||
});
|
||||
|
||||
test('Correctly parses error object when used with JSON.stringify()', () => {
|
||||
const errorMessage = 'Error Message';
|
||||
const errorCause = 'Error Cause';
|
||||
|
||||
const baseValue = {
|
||||
string: 'abc',
|
||||
num: 123,
|
||||
bool: true,
|
||||
null: null,
|
||||
};
|
||||
|
||||
const objWithError = {
|
||||
...baseValue,
|
||||
error: new Error(errorMessage, { cause: errorCause }),
|
||||
};
|
||||
|
||||
const expectedResult = {
|
||||
...baseValue,
|
||||
error: { name: 'Error', message: errorMessage, cause: errorCause },
|
||||
};
|
||||
|
||||
const result = JSON.parse(JSON.stringify(objWithError, errorReplacer));
|
||||
|
||||
// Stack changes depending on env
|
||||
expect(result.error.stack).toBeDefined();
|
||||
delete result.error.stack;
|
||||
|
||||
expect(result).toStrictEqual(expectedResult);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ type Paths = string[][];
|
||||
export function redact(input: UnknownObject, paths: Paths, replacement: string): UnknownObject {
|
||||
const wildcardChars = ['*', '**'];
|
||||
|
||||
const clone = structuredClone(input);
|
||||
const clone = JSON.parse(JSON.stringify(input, errorReplacer));
|
||||
const visited = new WeakSet<UnknownObject>();
|
||||
traverse(clone, paths);
|
||||
|
||||
@@ -86,3 +86,19 @@ export function redact(input: UnknownObject, paths: Paths, replacement: string):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract values from Error objects for use with JSON.stringify()
|
||||
*/
|
||||
export function errorReplacer(_key: string, value: unknown) {
|
||||
if (value instanceof Error) {
|
||||
return {
|
||||
name: value.name,
|
||||
message: value.message,
|
||||
stack: value.stack,
|
||||
cause: value.cause,
|
||||
};
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user