mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-06-16 19:13:21 +03:00
Force traceLimit
value modifying and restoring Error.stackTraceLimit
This commit is contained in:
parent
651df1a077
commit
d338dd96b4
|
@ -51,7 +51,7 @@ export default function configureStore(initialState) {
|
||||||
- **shouldStartLocked** *boolean* - if specified as `true`, it will not allow any non-monitor actions to be dispatched till `lockChanges(false)` is dispatched. Default is `false`.
|
- **shouldStartLocked** *boolean* - if specified as `true`, it will not allow any non-monitor actions to be dispatched till `lockChanges(false)` is dispatched. Default is `false`.
|
||||||
- **shouldHotReload** *boolean* - if set to `false`, will not recompute the states on hot reloading (or on replacing the reducers). Default to `true`.
|
- **shouldHotReload** *boolean* - if set to `false`, will not recompute the states on hot reloading (or on replacing the reducers). Default to `true`.
|
||||||
- **trace** *boolean* or *function* - if set to `true`, will include stack trace for every dispatched action. You can use a function (with action object as argument) which should return `new Error().stack` string, getting the stack outside of reducers. Default to `false`.
|
- **trace** *boolean* or *function* - if set to `true`, will include stack trace for every dispatched action. You can use a function (with action object as argument) which should return `new Error().stack` string, getting the stack outside of reducers. Default to `false`.
|
||||||
- **traceLimit** *number* - maximum stack trace frames to be stored (in case `trace` option was provided as `true`). By default it's `10`. Note that for Chrome there's a global limit to `10`, so you should also override the global `Error.stackTraceLimit` for more. If `trace` option is a function, `traceLimit` will have no effect, that should be handled there like so: `trace: () => new Error().stack.split('\n').slice(0, limit+1).join('\n')`. There's `+1` for `Error\n`.
|
- **traceLimit** *number* - maximum stack trace frames to be stored (in case `trace` option was provided as `true`). By default it's `10`. If `trace` option is a function, `traceLimit` will have no effect, that should be handled there like so: `trace: () => new Error().stack.split('\n').slice(0, limit+1).join('\n')` (`+1` is needed for Chrome where's an extra 1st frame for `Error\n`).
|
||||||
|
|
||||||
### License
|
### License
|
||||||
|
|
||||||
|
|
|
@ -39,17 +39,23 @@ export const ActionCreators = {
|
||||||
}
|
}
|
||||||
|
|
||||||
let stack;
|
let stack;
|
||||||
let error;
|
|
||||||
let frames;
|
|
||||||
if (trace) {
|
if (trace) {
|
||||||
if (typeof trace === 'function') stack = trace(action);
|
if (typeof trace === 'function') {
|
||||||
else {
|
stack = trace(action);
|
||||||
error = Error();
|
} else {
|
||||||
// https://v8.dev/docs/stack-trace-api#stack-trace-collection-for-custom-exceptions
|
const error = Error();
|
||||||
if (Error.captureStackTrace) Error.captureStackTrace(error, toExcludeFromTrace);
|
let prevStackTraceLimit;
|
||||||
|
if (Error.captureStackTrace) {
|
||||||
|
if (Error.stackTraceLimit < traceLimit) {
|
||||||
|
prevStackTraceLimit = Error.stackTraceLimit;
|
||||||
|
Error.stackTraceLimit = traceLimit;
|
||||||
|
}
|
||||||
|
Error.captureStackTrace(error, toExcludeFromTrace);
|
||||||
|
}
|
||||||
stack = error.stack;
|
stack = error.stack;
|
||||||
|
if (prevStackTraceLimit) Error.stackTraceLimit = prevStackTraceLimit;
|
||||||
if (typeof Error.stackTraceLimit !== 'number' || Error.stackTraceLimit > traceLimit) {
|
if (typeof Error.stackTraceLimit !== 'number' || Error.stackTraceLimit > traceLimit) {
|
||||||
frames = stack.split('\n');
|
const frames = stack.split('\n');
|
||||||
if (frames.length > traceLimit) {
|
if (frames.length > traceLimit) {
|
||||||
stack = frames.slice(0, traceLimit + (frames[0] === 'Error' ? 1 : 0)).join('\n');
|
stack = frames.slice(0, traceLimit + (frames[0] === 'Error' ? 1 : 0)).join('\n');
|
||||||
}
|
}
|
||||||
|
|
|
@ -738,32 +738,7 @@ describe('instrument', () => {
|
||||||
fn4();
|
fn4();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should include only 3 frames for stack trace when Error.stackTraceLimit is 3', () => {
|
it('should force traceLimit value of 3 when Error.stackTraceLimit is 10', () => {
|
||||||
const stackTraceLimit = Error.stackTraceLimit;
|
|
||||||
Error.stackTraceLimit = 3;
|
|
||||||
function fn1() {
|
|
||||||
monitoredStore = createStore(counter, instrument(undefined, { trace: true }));
|
|
||||||
monitoredLiftedStore = monitoredStore.liftedStore;
|
|
||||||
monitoredStore.dispatch({ type: 'INCREMENT' });
|
|
||||||
|
|
||||||
exportedState = monitoredLiftedStore.getState();
|
|
||||||
expect(exportedState.actionsById[0].stack).toBe(undefined);
|
|
||||||
expect(exportedState.actionsById[1].stack).toBeA('string');
|
|
||||||
expect(exportedState.actionsById[1].stack).toMatch(/at fn1 /);
|
|
||||||
expect(exportedState.actionsById[1].stack).toMatch(/at fn2 /);
|
|
||||||
expect(exportedState.actionsById[1].stack).toMatch(/at fn3 /);
|
|
||||||
expect(exportedState.actionsById[1].stack).toNotMatch(/at fn4 /);
|
|
||||||
expect(exportedState.actionsById[1].stack).toContain('instrument.spec.js');
|
|
||||||
expect(exportedState.actionsById[1].stack.split('\n').length).toBe(3 + 1);
|
|
||||||
}
|
|
||||||
function fn2() { return fn1(); }
|
|
||||||
function fn3() { return fn2(); }
|
|
||||||
function fn4() { return fn3(); }
|
|
||||||
fn4();
|
|
||||||
Error.stackTraceLimit = stackTraceLimit;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should include only 3 frames for stack trace when Error.stackTraceLimit is 10', () => {
|
|
||||||
const stackTraceLimit = Error.stackTraceLimit;
|
const stackTraceLimit = Error.stackTraceLimit;
|
||||||
Error.stackTraceLimit = 10;
|
Error.stackTraceLimit = 10;
|
||||||
function fn1() {
|
function fn1() {
|
||||||
|
@ -788,6 +763,48 @@ describe('instrument', () => {
|
||||||
Error.stackTraceLimit = stackTraceLimit;
|
Error.stackTraceLimit = stackTraceLimit;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should force traceLimit value of 5 even when Error.stackTraceLimit is 2', () => {
|
||||||
|
const stackTraceLimit = Error.stackTraceLimit;
|
||||||
|
Error.stackTraceLimit = 2;
|
||||||
|
monitoredStore = createStore(counter, instrument(undefined, { trace: true, traceLimit: 5 }));
|
||||||
|
monitoredLiftedStore = monitoredStore.liftedStore;
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
Error.stackTraceLimit = stackTraceLimit;
|
||||||
|
|
||||||
|
exportedState = monitoredLiftedStore.getState();
|
||||||
|
expect(exportedState.actionsById[0].stack).toBe(undefined);
|
||||||
|
expect(exportedState.actionsById[1].stack).toBeA('string');
|
||||||
|
expect(exportedState.actionsById[1].stack).toMatch(/^Error/);
|
||||||
|
expect(exportedState.actionsById[1].stack).toContain('instrument.spec.js');
|
||||||
|
expect(exportedState.actionsById[1].stack).toContain('/mocha/');
|
||||||
|
expect(exportedState.actionsById[1].stack.split('\n').length).toBe(5 + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should force default limit of 10 even when Error.stackTraceLimit is 3', () => {
|
||||||
|
const stackTraceLimit = Error.stackTraceLimit;
|
||||||
|
Error.stackTraceLimit = 3;
|
||||||
|
function fn1() {
|
||||||
|
monitoredStore = createStore(counter, instrument(undefined, { trace: true }));
|
||||||
|
monitoredLiftedStore = monitoredStore.liftedStore;
|
||||||
|
monitoredStore.dispatch({ type: 'INCREMENT' });
|
||||||
|
Error.stackTraceLimit = stackTraceLimit;
|
||||||
|
|
||||||
|
exportedState = monitoredLiftedStore.getState();
|
||||||
|
expect(exportedState.actionsById[0].stack).toBe(undefined);
|
||||||
|
expect(exportedState.actionsById[1].stack).toBeA('string');
|
||||||
|
expect(exportedState.actionsById[1].stack).toMatch(/at fn1 /);
|
||||||
|
expect(exportedState.actionsById[1].stack).toMatch(/at fn2 /);
|
||||||
|
expect(exportedState.actionsById[1].stack).toMatch(/at fn3 /);
|
||||||
|
expect(exportedState.actionsById[1].stack).toMatch(/at fn4 /);
|
||||||
|
expect(exportedState.actionsById[1].stack).toContain('instrument.spec.js');
|
||||||
|
expect(exportedState.actionsById[1].stack.split('\n').length).toBe(10 + 1);
|
||||||
|
}
|
||||||
|
function fn2() { return fn1(); }
|
||||||
|
function fn3() { return fn2(); }
|
||||||
|
function fn4() { return fn3(); }
|
||||||
|
fn4();
|
||||||
|
});
|
||||||
|
|
||||||
it('should get stack trace from a function', () => {
|
it('should get stack trace from a function', () => {
|
||||||
const traceFn = () => new Error().stack;
|
const traceFn = () => new Error().stack;
|
||||||
monitoredStore = createStore(counter, instrument(undefined, { trace: traceFn }));
|
monitoredStore = createStore(counter, instrument(undefined, { trace: traceFn }));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user