browser_dbg-pause-exceptions.js (5424B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ 4 5 /* 6 Tests Pausing on exception 7 1. skip an uncaught exception 8 2. pause on an uncaught exception 9 3. pause on a caught error 10 4. skip a caught error 11 */ 12 13 "use strict"; 14 15 const { PromiseTestUtils } = ChromeUtils.importESModule( 16 "resource://testing-common/PromiseTestUtils.sys.mjs" 17 ); 18 // This is step 9 19 PromiseTestUtils.allowMatchingRejectionsGlobally(/doesntExists is not defined/); 20 21 add_task(async function () { 22 const dbg = await initDebugger("doc-exceptions.html", "exceptions.js"); 23 const source = findSource(dbg, "exceptions.js"); 24 25 info("1. test skipping an uncaught exception"); 26 await uncaughtException(); 27 assertNotPaused(dbg); 28 29 info("2. Test pausing on an uncaught exception"); 30 await togglePauseOnExceptions(dbg, true, true); 31 uncaughtException(); 32 await waitForPaused(dbg); 33 await assertPausedAtSourceAndLine(dbg, source.id, 2); 34 35 const whyPaused = await waitFor( 36 () => dbg.win.document.querySelector(".why-paused")?.innerText 37 ); 38 is( 39 whyPaused, 40 `Paused on exception\nuncaughtException - exceptions.js:2:2\nunreachable` 41 ); 42 43 await resume(dbg); 44 45 info("2.b Test throwing the same uncaught exception pauses again"); 46 await togglePauseOnExceptions(dbg, true, true); 47 uncaughtException(); 48 await waitForPaused(dbg); 49 await assertPausedAtSourceAndLine(dbg, source.id, 2); 50 await resume(dbg); 51 52 info("3. Test pausing on a caught Error"); 53 caughtException(); 54 await waitForPaused(dbg); 55 await assertPausedAtSourceAndLine(dbg, source.id, 7); 56 57 info("3.b Test pausing in the catch statement"); 58 await resume(dbg); 59 await waitForPaused(dbg); 60 await assertPausedAtSourceAndLine(dbg, source.id, 9); 61 await resume(dbg); 62 63 info("4. Test skipping a caught error"); 64 await togglePauseOnExceptions(dbg, true, false); 65 caughtException(); 66 67 info("4.b Test pausing in the catch statement"); 68 await waitForPaused(dbg); 69 await assertPausedAtSourceAndLine(dbg, source.id, 9); 70 await resume(dbg); 71 72 await togglePauseOnExceptions(dbg, true, true); 73 74 info("5. Only pause once when throwing deep in the stack"); 75 invokeInTab("deepError"); 76 await waitForPaused(dbg); 77 await assertPausedAtSourceAndLine(dbg, source.id, 16); 78 await resume(dbg); 79 await waitForPaused(dbg); 80 await assertPausedAtSourceAndLine(dbg, source.id, 22); 81 await resume(dbg); 82 83 info("6. Only pause once on an exception when pausing in a finally block"); 84 invokeInTab("deepErrorFinally"); 85 await waitForPaused(dbg); 86 await assertPausedAtSourceAndLine(dbg, source.id, 34); 87 await resume(dbg); 88 await waitForPaused(dbg); 89 await assertPausedAtSourceAndLine(dbg, source.id, 31); 90 await resume(dbg); 91 await waitForPaused(dbg); 92 await assertPausedAtSourceAndLine(dbg, source.id, 40); 93 await resume(dbg); 94 95 info("7. Only pause once on an exception when it is rethrown from a catch"); 96 invokeInTab("deepErrorCatch"); 97 await waitForPaused(dbg); 98 await assertPausedAtSourceAndLine(dbg, source.id, 53); 99 await resume(dbg); 100 await waitForPaused(dbg); 101 await assertPausedAtSourceAndLine(dbg, source.id, 49); 102 await resume(dbg); 103 await waitForPaused(dbg); 104 await assertPausedAtSourceAndLine(dbg, source.id, 59); 105 await resume(dbg); 106 107 info("8. Pause on each exception thrown while unwinding"); 108 invokeInTab("deepErrorThrowDifferent"); 109 await waitForPaused(dbg); 110 await assertPausedAtSourceAndLine(dbg, source.id, 71); 111 await resume(dbg); 112 await waitForPaused(dbg); 113 await assertPausedAtSourceAndLine(dbg, source.id, 68); 114 await resume(dbg); 115 await waitForPaused(dbg); 116 await assertPausedAtSourceAndLine(dbg, source.id, 77); 117 await resume(dbg); 118 119 info("9. Pause in throwing new Function argument"); 120 const onNewSource = waitForDispatch(dbg.store, "ADD_SOURCES"); 121 invokeInTab("throwInNewFunctionArgument"); 122 await waitForPaused(dbg); 123 const { sources } = await onNewSource; 124 is(sources.length, 1, "Got a unique source related to new Function source"); 125 const newFunctionSource = sources[0]; 126 is( 127 newFunctionSource.url, 128 null, 129 "This new source looks like the new function one as it has no url" 130 ); 131 await assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 1, 0); 132 assertTextContentOnLine(dbg, 1, "function anonymous(f=doesntExists()"); 133 await resume(dbg); 134 }); 135 136 add_task(async function testSettingAppliedOnStartup() { 137 let dbg = await initDebugger("doc-exceptions.html", "exceptions.js"); 138 139 await togglePauseOnExceptions(dbg, true, true); 140 141 await dbg.toolbox.closeToolbox(); 142 143 // Do not use `initDebugger` as it resets all settings 144 const toolbox = await openNewTabAndToolbox( 145 EXAMPLE_URL + "doc-exceptions.html", 146 "jsdebugger" 147 ); 148 dbg = createDebuggerContext(toolbox); 149 150 await waitForSource(dbg, "exceptions.js"); 151 152 const pauseOnCaughtExceptionCheckbox = findElementWithSelector( 153 dbg, 154 ".breakpoints-exceptions-caught input" 155 ); 156 ok(pauseOnCaughtExceptionCheckbox.checked, "The settings is visualy enabled"); 157 158 uncaughtException(); 159 await waitForPaused(dbg); 160 await assertPausedAtSourceAndLine( 161 dbg, 162 findSource(dbg, "exceptions.js").id, 163 2 164 ); 165 }); 166 167 function uncaughtException() { 168 return invokeInTab("uncaughtException").catch(() => {}); 169 } 170 171 function caughtException() { 172 return invokeInTab("caughtException"); 173 }