• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3common.skipIfInspectorDisabled();
4const assert = require('assert');
5const inspector = require('inspector');
6const path = require('path');
7const { pathToFileURL } = require('url');
8
9// This test case will set a breakpoint 4 lines below
10function debuggedFunction() {
11  let i;
12  let accum = 0;
13  for (i = 0; i < 5; i++) {
14    accum += i;
15  }
16  return accum;
17}
18
19let scopeCallback = null;
20
21function checkScope(session, scopeId) {
22  session.post('Runtime.getProperties', {
23    'objectId': scopeId,
24    'ownProperties': false,
25    'accessorPropertiesOnly': false,
26    'generatePreview': true
27  }, scopeCallback);
28}
29
30function debuggerPausedCallback(session, notification) {
31  const params = notification.params;
32  const callFrame = params.callFrames[0];
33  const scopeId = callFrame.scopeChain[0].object.objectId;
34  checkScope(session, scopeId);
35}
36
37function waitForWarningSkipAsyncStackTraces(resolve) {
38  process.once('warning', function(warning) {
39    if (warning.code === 'INSPECTOR_ASYNC_STACK_TRACES_NOT_AVAILABLE') {
40      waitForWarningSkipAsyncStackTraces(resolve);
41    } else {
42      resolve(warning);
43    }
44  });
45}
46
47async function testNoCrashWithExceptionInCallback() {
48  // There is a deliberate exception in the callback
49  const session = new inspector.Session();
50  session.connect();
51  const error = new Error('We expect this');
52  console.log('Expecting warning to be emitted');
53  const promise = new Promise(waitForWarningSkipAsyncStackTraces);
54  session.post('Console.enable', () => { throw error; });
55  assert.strictEqual(await promise, error);
56  session.disconnect();
57}
58
59function testSampleDebugSession() {
60  let cur = 0;
61  const failures = [];
62  const expects = {
63    i: [0, 1, 2, 3, 4],
64    accum: [0, 0, 1, 3, 6]
65  };
66  scopeCallback = function(error, result) {
67    const i = cur++;
68    let v, actual, expected;
69    for (v of result.result) {
70      actual = v.value.value;
71      expected = expects[v.name][i];
72      if (actual !== expected) {
73        failures.push(`Iteration ${i} variable: ${v.name} ` +
74          `expected: ${expected} actual: ${actual}`);
75      }
76    }
77  };
78  const session = new inspector.Session();
79  session.connect();
80  session.on('Debugger.paused',
81             (notification) => debuggerPausedCallback(session, notification));
82  let cbAsSecondArgCalled = false;
83  assert.throws(() => {
84    session.post('Debugger.enable', function() {}, function() {});
85  }, TypeError);
86  session.post('Debugger.enable', () => cbAsSecondArgCalled = true);
87  session.post('Debugger.setBreakpointByUrl', {
88    'lineNumber': 13,
89    'url': pathToFileURL(path.resolve(__dirname, __filename)).toString(),
90    'columnNumber': 0,
91    'condition': ''
92  });
93
94  debuggedFunction();
95  assert.deepStrictEqual(cbAsSecondArgCalled, true);
96  assert.deepStrictEqual(failures, []);
97  assert.strictEqual(cur, 5);
98  scopeCallback = null;
99  session.disconnect();
100  assert.throws(() => session.post('Debugger.enable'), (e) => !!e);
101}
102
103async function testNoCrashConsoleLogBeforeThrow() {
104  const session = new inspector.Session();
105  session.connect();
106  let attempt = 1;
107  process.on('warning', common.mustCall(3));
108  session.on('inspectorNotification', () => {
109    if (attempt++ > 3)
110      return;
111    console.log('console.log in handler');
112    throw new Error('Exception in handler');
113  });
114  session.post('Runtime.enable');
115  console.log('Did not crash');
116  session.disconnect();
117}
118
119async function doTests() {
120  await testNoCrashWithExceptionInCallback();
121  testSampleDebugSession();
122  let breakpointHit = false;
123  scopeCallback = () => (breakpointHit = true);
124  debuggedFunction();
125  assert.strictEqual(breakpointHit, false);
126  testSampleDebugSession();
127  await testNoCrashConsoleLogBeforeThrow();
128}
129
130doTests().then(common.mustCall());
131