Errors.sys.mjs (29734B)
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 file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { RemoteError } from "chrome://remote/content/shared/RemoteError.sys.mjs"; 6 7 const lazy = {}; 8 9 ChromeUtils.defineESModuleGetters(lazy, { 10 pprint: "chrome://remote/content/shared/Format.sys.mjs", 11 }); 12 13 const ERRORS = new Set([ 14 "DetachedShadowRootError", 15 "ElementClickInterceptedError", 16 "ElementNotAccessibleError", 17 "ElementNotInteractableError", 18 "InsecureCertificateError", 19 "InvalidArgumentError", 20 "InvalidCookieDomainError", 21 "InvalidElementStateError", 22 "InvalidSelectorError", 23 "InvalidSessionIDError", 24 "InvalidWebExtensionError", 25 "JavaScriptError", 26 "MoveTargetOutOfBoundsError", 27 "NoSuchAlertError", 28 "NoSuchElementError", 29 "NoSuchFrameError", 30 "NoSuchHandleError", 31 "NoSuchHistoryEntryError", 32 "NoSuchInterceptError", 33 "NoSuchNetworkCollectorError", 34 "NoSuchNetworkDataError", 35 "NoSuchNodeError", 36 "NoSuchRequestError", 37 "NoSuchScriptError", 38 "NoSuchShadowRootError", 39 "NoSuchUserContextError", 40 "NoSuchWebExtensionError", 41 "NoSuchWindowError", 42 "ScriptTimeoutError", 43 "SessionNotCreatedError", 44 "StaleElementReferenceError", 45 "TimeoutError", 46 "UnableToCaptureScreen", 47 "UnableToSetCookieError", 48 "UnableToSetFileInputError", 49 "UnavailableNetworkDataError", 50 "UnexpectedAlertOpenError", 51 "UnknownCommandError", 52 "UnknownError", 53 "UnsupportedOperationError", 54 "WebDriverError", 55 ]); 56 57 const BUILTIN_ERRORS = new Set([ 58 "Error", 59 "EvalError", 60 "InternalError", 61 "RangeError", 62 "ReferenceError", 63 "SyntaxError", 64 "TypeError", 65 "URIError", 66 ]); 67 68 /** @namespace */ 69 export const error = { 70 /** 71 * Check if ``val`` is an instance of the ``Error`` prototype. 72 * 73 * Because error objects may originate from different globals, comparing 74 * the prototype of the left hand side with the prototype property from 75 * the right hand side, which is what ``instanceof`` does, will not work. 76 * If the LHS and RHS come from different globals, this check will always 77 * fail because the two objects will not have the same identity. 78 * 79 * Therefore it is not safe to use ``instanceof`` in any multi-global 80 * situation, e.g. in content across multiple ``Window`` objects or anywhere 81 * in chrome scope. 82 * 83 * This function also contains a special check if ``val`` is an XPCOM 84 * ``nsIException`` because they are special snowflakes and may indeed 85 * cause Firefox to crash if used with ``instanceof``. 86 * 87 * @param {*} val 88 * Any value that should be undergo the test for errorness. 89 * @returns {boolean} 90 * True if error, false otherwise. 91 */ 92 isError(val) { 93 if (val === null || typeof val != "object") { 94 return false; 95 } else if (val instanceof Ci.nsIException) { 96 return true; 97 } 98 99 // DOMRectList errors on string comparison 100 try { 101 let proto = Object.getPrototypeOf(val); 102 return BUILTIN_ERRORS.has(proto.toString()); 103 } catch (e) { 104 return false; 105 } 106 }, 107 108 /** 109 * Checks if ``obj`` is an object in the :js:class:`WebDriverError` 110 * prototypal chain. 111 * 112 * @param {*} obj 113 * Arbitrary object to test. 114 * 115 * @returns {boolean} 116 * True if ``obj`` is of the WebDriverError prototype chain, 117 * false otherwise. 118 */ 119 isWebDriverError(obj) { 120 // Don't use "instanceof" to compare error objects because of possible 121 // problems when the other instance was created in a different global and 122 // as such won't have the same prototype object. 123 return error.isError(obj) && "name" in obj && ERRORS.has(obj.name); 124 }, 125 126 /** 127 * Ensures error instance is a :js:class:`WebDriverError`. 128 * 129 * If the given error is already in the WebDriverError prototype 130 * chain, ``err`` is returned unmodified. If it is not, it is wrapped 131 * in the provided WebDriverError class (defaults to :js:class:`UnknownError`). 132 * 133 * @param {Error} err 134 * Error to conditionally turn into a WebDriverError. 135 * @param {WebDriverError=} targetErrorClass 136 * Target WebDriver error class to wrap the error with. 137 * Defaults to UnknownError. 138 * 139 * @returns {WebDriverError} 140 * If ``err`` is a WebDriverError, it is returned unmodified. 141 * Otherwise a WebDriver error of the target error class type is returned. 142 */ 143 wrap(err, targetErrorClass = UnknownError) { 144 if (error.isWebDriverError(err)) { 145 return err; 146 } 147 148 return new targetErrorClass(err); 149 }, 150 151 /** 152 * Unhandled error reporter. Dumps the error and its stacktrace to console, 153 * and reports error to the Browser Console. 154 */ 155 report(err) { 156 let msg = "Marionette threw an error: " + error.stringify(err); 157 dump(msg + "\n"); 158 console.error(msg); 159 }, 160 161 /** 162 * Prettifies an instance of Error and its stacktrace to a string. 163 */ 164 stringify(err) { 165 try { 166 let s = err.toString(); 167 if ("stack" in err) { 168 s += "\n" + err.stack; 169 } 170 return s; 171 } catch (e) { 172 return "<unprintable error>"; 173 } 174 }, 175 176 /** Create a stacktrace to the current line in the program. */ 177 stack() { 178 let trace = new Error().stack; 179 let sa = trace.split("\n"); 180 sa = sa.slice(1); 181 let rv = "stacktrace:\n" + sa.join("\n"); 182 return rv.trimEnd(); 183 }, 184 }; 185 186 /** 187 * WebDriverError is the prototypal parent of all WebDriver errors. 188 * It should not be used directly, as it does not correspond to a real 189 * error in the specification. 190 */ 191 class WebDriverError extends RemoteError { 192 /** 193 * Base error for WebDriver protocols. 194 * 195 * @param {(string|Error)=} obj 196 * Optional string describing error situation or Error instance 197 * to propagate. 198 * @param {object=} data 199 * Additional error data helpful in diagnosing the error. 200 */ 201 constructor(obj, data = {}) { 202 super(obj); 203 204 this.name = this.constructor.name; 205 this.status = "webdriver error"; 206 this.data = data; 207 208 // Error's ctor does not preserve x' stack 209 if (error.isError(obj)) { 210 this.lineNumber = obj.lineNumber; 211 this.columnNumber = obj.columnNumber; 212 if (!obj.stack) { 213 // Provides a stacktrace if it was missing on the original Error object 214 this.stack = `@${obj.fileName}:${obj.lineNumber}:${obj.columnNumber}\n`; 215 } else { 216 this.stack = obj.stack; 217 } 218 } 219 220 if (error.isWebDriverError(obj)) { 221 this.message = obj.message; 222 this.data = obj.data; 223 } 224 } 225 226 /** 227 * @returns {Record<string, string>} 228 * JSON serialisation of error prototype. 229 */ 230 toJSON() { 231 const result = { 232 error: this.status, 233 message: this.message || "", 234 stacktrace: this.stack || "", 235 }; 236 237 // Only add the field if additional data has been specified. 238 if (Object.keys(this.data).length) { 239 result.data = this.data; 240 } 241 242 return result; 243 } 244 245 /** 246 * Unmarshals a JSON error representation to the appropriate Marionette 247 * error type. 248 * 249 * @param {Record<string, string>} json 250 * Error object. 251 * 252 * @returns {Error} 253 * Error prototype. 254 */ 255 static fromJSON(json) { 256 if (typeof json.error == "undefined") { 257 let s = JSON.stringify(json); 258 throw new TypeError("Undeserialisable error type: " + s); 259 } 260 if (!STATUSES.has(json.error)) { 261 throw new TypeError("Not of WebDriverError descent: " + json.error); 262 } 263 264 let cls = STATUSES.get(json.error); 265 let err = new cls(); 266 if ("message" in json) { 267 err.message = json.message; 268 } 269 if ("stacktrace" in json) { 270 err.stack = json.stacktrace; 271 } 272 if ("data" in json) { 273 err.data = json.data; 274 } 275 276 return err; 277 } 278 } 279 280 /** 281 * The Gecko a11y API indicates that the element is not accessible. 282 * 283 * @param {(string|Error)=} obj 284 * Optional string describing error situation or Error instance 285 * to propagate. 286 * @param {object=} data 287 * Additional error data helpful in diagnosing the error. 288 */ 289 class ElementNotAccessibleError extends WebDriverError { 290 constructor(obj, data = {}) { 291 super(obj, data); 292 this.status = "element not accessible"; 293 } 294 } 295 296 /** 297 * An element click could not be completed because the element receiving 298 * the events is obscuring the element that was requested clicked. 299 * 300 * @param {string=} message 301 * Optional string describing error situation. Will be replaced if both 302 * `data.obscuredEl` and `data.coords` are provided. 303 * @param {object=} data 304 * Additional error data helpful in diagnosing the error. 305 * @param {Element=} obscuredEl 306 * Element obscuring the element receiving the click. Providing this 307 * is not required, but will produce a nicer error message. 308 * @param {Map.<string, number>=} coords 309 * Original click location. Providing this is not required, but 310 * will produce a nicer error message. 311 */ 312 class ElementClickInterceptedError extends WebDriverError { 313 constructor(obj, data = {}, obscuredEl = undefined, coords = undefined) { 314 let obscuredElDetails = null; 315 let overlayingElDetails = null; 316 317 if (obscuredEl && coords) { 318 const doc = obscuredEl.ownerDocument; 319 const overlayingEl = doc.elementFromPoint(coords.x, coords.y); 320 321 obscuredElDetails = lazy.pprint`${obscuredEl}`; 322 overlayingElDetails = lazy.pprint`${overlayingEl}`; 323 324 switch (obscuredEl.style.pointerEvents) { 325 case "none": 326 obj = 327 `Element ${obscuredElDetails} is not clickable ` + 328 `at point (${coords.x},${coords.y}) ` + 329 `because it does not have pointer events enabled, ` + 330 `and element ${overlayingElDetails} ` + 331 `would receive the click instead`; 332 break; 333 334 default: 335 obj = 336 `Element ${obscuredElDetails} is not clickable ` + 337 `at point (${coords.x},${coords.y}) ` + 338 `because another element ${overlayingElDetails} ` + 339 `obscures it`; 340 break; 341 } 342 } 343 344 if (coords) { 345 data.coords = coords; 346 } 347 if (obscuredElDetails) { 348 data.obscuredElement = obscuredElDetails; 349 } 350 if (overlayingElDetails) { 351 data.overlayingElement = overlayingElDetails; 352 } 353 354 super(obj, data); 355 this.status = "element click intercepted"; 356 } 357 } 358 359 /** 360 * A command could not be completed because the element is not pointer- 361 * or keyboard interactable. 362 * 363 * @param {(string|Error)=} obj 364 * Optional string describing error situation or Error instance 365 * to propagate. 366 * @param {object=} data 367 * Additional error data helpful in diagnosing the error. 368 */ 369 class ElementNotInteractableError extends WebDriverError { 370 constructor(obj, data = {}) { 371 super(obj, data); 372 this.status = "element not interactable"; 373 } 374 } 375 376 /** 377 * Navigation caused the user agent to hit a certificate warning, which 378 * is usually the result of an expired or invalid TLS certificate. 379 * 380 * @param {(string|Error)=} obj 381 * Optional string describing error situation or Error instance 382 * to propagate. 383 * @param {object=} data 384 * Additional error data helpful in diagnosing the error. 385 */ 386 class InsecureCertificateError extends WebDriverError { 387 constructor(obj, data = {}) { 388 super(obj, data); 389 this.status = "insecure certificate"; 390 } 391 } 392 393 /** 394 * The arguments passed to a command are either invalid or malformed. 395 * 396 * @param {(string|Error)=} obj 397 * Optional string describing error situation or Error instance 398 * to propagate. 399 * @param {object=} data 400 * Additional error data helpful in diagnosing the error. 401 */ 402 class InvalidArgumentError extends WebDriverError { 403 constructor(obj, data = {}) { 404 super(obj, data); 405 this.status = "invalid argument"; 406 } 407 } 408 409 /** 410 * An illegal attempt was made to set a cookie under a different 411 * domain than the current page. 412 * 413 * @param {(string|Error)=} obj 414 * Optional string describing error situation or Error instance 415 * to propagate. 416 * @param {object=} data 417 * Additional error data helpful in diagnosing the error. 418 */ 419 class InvalidCookieDomainError extends WebDriverError { 420 constructor(obj, data = {}) { 421 super(obj, data); 422 this.status = "invalid cookie domain"; 423 } 424 } 425 426 /** 427 * A command could not be completed because the element is in an 428 * invalid state, e.g. attempting to clear an element that isn't both 429 * editable and resettable. 430 * 431 * @param {(string|Error)=} obj 432 * Optional string describing error situation or Error instance 433 * to propagate. 434 * @param {object=} data 435 * Additional error data helpful in diagnosing the error. 436 */ 437 class InvalidElementStateError extends WebDriverError { 438 constructor(obj, data = {}) { 439 super(obj, data); 440 this.status = "invalid element state"; 441 } 442 } 443 444 /** 445 * Argument was an invalid selector. 446 * 447 * @param {(string|Error)=} obj 448 * Optional string describing error situation or Error instance 449 * to propagate. 450 * @param {object=} data 451 * Additional error data helpful in diagnosing the error. 452 */ 453 class InvalidSelectorError extends WebDriverError { 454 constructor(obj, data = {}) { 455 super(obj, data); 456 this.status = "invalid selector"; 457 } 458 } 459 460 /** 461 * Occurs if the given session ID is not in the list of active sessions, 462 * meaning the session either does not exist or that it's not active. 463 * 464 * @param {(string|Error)=} obj 465 * Optional string describing error situation or Error instance 466 * to propagate. 467 * @param {object=} data 468 * Additional error data helpful in diagnosing the error. 469 */ 470 class InvalidSessionIDError extends WebDriverError { 471 constructor(obj, data = {}) { 472 super(obj, data); 473 this.status = "invalid session id"; 474 } 475 } 476 477 /** 478 * Tried to install an invalid web extension. 479 * 480 * @param {(string|Error)=} obj 481 * Optional string describing error situation or Error instance 482 * to propagate. 483 * @param {object=} data 484 * Additional error data helpful in diagnosing the error. 485 */ 486 class InvalidWebExtensionError extends WebDriverError { 487 constructor(obj, data = {}) { 488 super(obj, data); 489 this.status = "invalid web extension"; 490 } 491 } 492 493 /** 494 * An error occurred whilst executing JavaScript supplied by the user. 495 * 496 * @param {(string|Error)=} obj 497 * Optional string describing error situation or Error instance 498 * to propagate. 499 * @param {object=} data 500 * Additional error data helpful in diagnosing the error. 501 */ 502 class JavaScriptError extends WebDriverError { 503 constructor(obj, data = {}) { 504 super(obj, data); 505 this.status = "javascript error"; 506 } 507 } 508 509 /** 510 * The target for mouse interaction is not in the browser's viewport 511 * and cannot be brought into that viewport. 512 * 513 * @param {(string|Error)=} obj 514 * Optional string describing error situation or Error instance 515 * to propagate. 516 * @param {object=} data 517 * Additional error data helpful in diagnosing the error. 518 */ 519 class MoveTargetOutOfBoundsError extends WebDriverError { 520 constructor(obj, data = {}) { 521 super(obj, data); 522 this.status = "move target out of bounds"; 523 } 524 } 525 526 /** 527 * An attempt was made to operate on a modal dialog when one was 528 * not open. 529 * 530 * @param {(string|Error)=} obj 531 * Optional string describing error situation or Error instance 532 * to propagate. 533 * @param {object=} data 534 * Additional error data helpful in diagnosing the error. 535 */ 536 class NoSuchAlertError extends WebDriverError { 537 constructor(obj, data = {}) { 538 super(obj, data); 539 this.status = "no such alert"; 540 } 541 } 542 543 /** 544 * An element could not be located on the page using the given 545 * search parameters. 546 * 547 * @param {(string|Error)=} obj 548 * Optional string describing error situation or Error instance 549 * to propagate. 550 * @param {object=} data 551 * Additional error data helpful in diagnosing the error. 552 */ 553 class NoSuchElementError extends WebDriverError { 554 constructor(obj, data = {}) { 555 super(obj, data); 556 this.status = "no such element"; 557 } 558 } 559 560 /** 561 * A command tried to remove an unknown preload script. 562 * 563 * @param {(string|Error)=} obj 564 * Optional string describing error situation or Error instance 565 * to propagate. 566 * @param {object=} data 567 * Additional error data helpful in diagnosing the error. 568 */ 569 class NoSuchScriptError extends WebDriverError { 570 constructor(obj, data = {}) { 571 super(obj, data); 572 this.status = "no such script"; 573 } 574 } 575 576 /** 577 * A shadow root was not attached to the element. 578 * 579 * @param {(string|Error)=} obj 580 * Optional string describing error situation or Error instance 581 * to propagate. 582 * @param {object=} data 583 * Additional error data helpful in diagnosing the error. 584 */ 585 class NoSuchShadowRootError extends WebDriverError { 586 constructor(obj, data = {}) { 587 super(obj, data); 588 this.status = "no such shadow root"; 589 } 590 } 591 592 /** 593 * A shadow root is no longer attached to the document. 594 * 595 * @param {(string|Error)=} obj 596 * Optional string describing error situation or Error instance 597 * to propagate. 598 * @param {object=} data 599 * Additional error data helpful in diagnosing the error. 600 */ 601 class DetachedShadowRootError extends WebDriverError { 602 constructor(obj, data = {}) { 603 super(obj, data); 604 this.status = "detached shadow root"; 605 } 606 } 607 608 /** 609 * A command to switch to a frame could not be satisfied because 610 * the frame could not be found. 611 * 612 * @param {(string|Error)=} obj 613 * Optional string describing error situation or Error instance 614 * to propagate. 615 * @param {object=} data 616 * Additional error data helpful in diagnosing the error. 617 */ 618 class NoSuchFrameError extends WebDriverError { 619 constructor(obj, data = {}) { 620 super(obj, data); 621 this.status = "no such frame"; 622 } 623 } 624 625 /** 626 * The handle of a strong object reference could not be found. 627 * 628 * @param {(string|Error)=} obj 629 * Optional string describing error situation or Error instance 630 * to propagate. 631 * @param {object=} data 632 * Additional error data helpful in diagnosing the error. 633 */ 634 class NoSuchHandleError extends WebDriverError { 635 constructor(obj, data = {}) { 636 super(obj, data); 637 this.status = "no such handle"; 638 } 639 } 640 641 /** 642 * The entry of the history could not be found. 643 * 644 * @param {(string|Error)=} obj 645 * Optional string describing error situation or Error instance 646 * to propagate. 647 * @param {object=} data 648 * Additional error data helpful in diagnosing the error. 649 */ 650 class NoSuchHistoryEntryError extends WebDriverError { 651 constructor(obj, data = {}) { 652 super(obj, data); 653 this.status = "no such history entry"; 654 } 655 } 656 657 /** 658 * Tried to remove an unknown network intercept. 659 * 660 * @param {(string|Error)=} obj 661 * Optional string describing error situation or Error instance 662 * to propagate. 663 * @param {object=} data 664 * Additional error data helpful in diagnosing the error. 665 */ 666 class NoSuchInterceptError extends WebDriverError { 667 constructor(obj, data = {}) { 668 super(obj, data); 669 this.status = "no such intercept"; 670 } 671 } 672 673 /** 674 * A network data collector with the given unique id could not be found. 675 * 676 * @param {(string|Error)=} obj 677 * Optional string describing error situation or Error instance 678 * to propagate. 679 * @param {object=} data 680 * Additional error data helpful in diagnosing the error. 681 */ 682 class NoSuchNetworkCollectorError extends WebDriverError { 683 constructor(obj, data = {}) { 684 super(obj, data); 685 this.status = "no such network collector"; 686 } 687 } 688 689 /** 690 * A network data for the provided request id and data type could not be found. 691 * 692 * @param {(string|Error)=} obj 693 * Optional string describing error situation or Error instance 694 * to propagate. 695 * @param {object=} data 696 * Additional error data helpful in diagnosing the error. 697 */ 698 class NoSuchNetworkDataError extends WebDriverError { 699 constructor(obj, data = {}) { 700 super(obj, data); 701 this.status = "no such network data"; 702 } 703 } 704 705 /** 706 * A node as given by its unique shared id could not be found within the cache 707 * of known nodes. 708 * 709 * @param {(string|Error)=} obj 710 * Optional string describing error situation or Error instance 711 * to propagate. 712 * @param {object=} data 713 * Additional error data helpful in diagnosing the error. 714 */ 715 class NoSuchNodeError extends WebDriverError { 716 constructor(obj, data = {}) { 717 super(obj, data); 718 this.status = "no such node"; 719 } 720 } 721 722 /** 723 * Tried to continue an unknown request. 724 * 725 * @param {(string|Error)=} obj 726 * Optional string describing error situation or Error instance 727 * to propagate. 728 * @param {object=} data 729 * Additional error data helpful in diagnosing the error. 730 */ 731 class NoSuchRequestError extends WebDriverError { 732 constructor(obj, data = {}) { 733 super(obj, data); 734 this.status = "no such request"; 735 } 736 } 737 738 /** 739 * A command tried to reference an unknown user context (containers in Firefox). 740 * 741 * @param {(string|Error)=} obj 742 * Optional string describing error situation or Error instance 743 * to propagate. 744 * @param {object=} data 745 * Additional error data helpful in diagnosing the error. 746 */ 747 class NoSuchUserContextError extends WebDriverError { 748 constructor(obj, data = {}) { 749 super(obj, data); 750 this.status = "no such user context"; 751 } 752 } 753 754 /** 755 * A command tried to reference an unknown web extension. 756 * 757 * @param {(string|Error)=} obj 758 * Optional string describing error situation or Error instance 759 * to propagate. 760 * @param {object=} data 761 * Additional error data helpful in diagnosing the error. 762 */ 763 class NoSuchWebExtensionError extends WebDriverError { 764 constructor(obj, data = {}) { 765 super(obj, data); 766 this.status = "no such web extension"; 767 } 768 } 769 770 /** 771 * A command to switch to a window could not be satisfied because 772 * the window could not be found. 773 * 774 * @param {(string|Error)=} obj 775 * Optional string describing error situation or Error instance 776 * to propagate. 777 * @param {object=} data 778 * Additional error data helpful in diagnosing the error. 779 */ 780 class NoSuchWindowError extends WebDriverError { 781 constructor(obj, data = {}) { 782 super(obj, data); 783 this.status = "no such window"; 784 } 785 } 786 787 /** 788 * A script did not complete before its timeout expired. 789 * 790 * @param {(string|Error)=} obj 791 * Optional string describing error situation or Error instance 792 * to propagate. 793 * @param {object=} data 794 * Additional error data helpful in diagnosing the error. 795 */ 796 class ScriptTimeoutError extends WebDriverError { 797 constructor(obj, data = {}) { 798 super(obj, data); 799 this.status = "script timeout"; 800 } 801 } 802 803 /** 804 * A new session could not be created. 805 * 806 * @param {(string|Error)=} obj 807 * Optional string describing error situation or Error instance 808 * to propagate. 809 * @param {object=} data 810 * Additional error data helpful in diagnosing the error. 811 */ 812 class SessionNotCreatedError extends WebDriverError { 813 constructor(obj, data = {}) { 814 super(obj, data); 815 this.status = "session not created"; 816 } 817 } 818 819 /** 820 * A command failed because the referenced element is no longer 821 * attached to the DOM. 822 * 823 * @param {(string|Error)=} obj 824 * Optional string describing error situation or Error instance 825 * to propagate. 826 * @param {object=} data 827 * Additional error data helpful in diagnosing the error. 828 */ 829 class StaleElementReferenceError extends WebDriverError { 830 constructor(obj, options = {}) { 831 super(obj, options); 832 this.status = "stale element reference"; 833 } 834 } 835 836 /** 837 * An operation did not complete before its timeout expired. 838 * 839 * @param {(string|Error)=} obj 840 * Optional string describing error situation or Error instance 841 * to propagate. 842 * @param {object=} data 843 * Additional error data helpful in diagnosing the error. 844 */ 845 class TimeoutError extends WebDriverError { 846 constructor(obj, data = {}) { 847 super(obj, data); 848 this.status = "timeout"; 849 } 850 } 851 852 /** 853 * A command to set a cookie's value could not be satisfied. 854 * 855 * @param {(string|Error)=} obj 856 * Optional string describing error situation or Error instance 857 * to propagate. 858 * @param {object=} data 859 * Additional error data helpful in diagnosing the error. 860 */ 861 class UnableToSetCookieError extends WebDriverError { 862 constructor(obj, data = {}) { 863 super(obj, data); 864 this.status = "unable to set cookie"; 865 } 866 } 867 868 /** 869 * A command to set a file could not be satisfied. 870 * 871 * @param {(string|Error)=} obj 872 * Optional string describing error situation or Error instance 873 * to propagate. 874 * @param {object=} data 875 * Additional error data helpful in diagnosing the error. 876 */ 877 class UnableToSetFileInputError extends WebDriverError { 878 constructor(obj, data = {}) { 879 super(obj, data); 880 this.status = "unable to set file input"; 881 } 882 } 883 884 /** 885 * A command to capture a screenshot could not be satisfied. 886 * 887 * @param {(string|Error)=} obj 888 * Optional string describing error situation or Error instance 889 * to propagate. 890 * @param {object=} data 891 * Additional error data helpful in diagnosing the error. 892 */ 893 class UnableToCaptureScreen extends WebDriverError { 894 constructor(obj, data = {}) { 895 super(obj, data); 896 this.status = "unable to capture screen"; 897 } 898 } 899 900 /** 901 * A network data content is not available. 902 * 903 * @param {(string|Error)=} obj 904 * Optional string describing error situation or Error instance 905 * to propagate. 906 * @param {object=} data 907 * Additional error data helpful in diagnosing the error. 908 */ 909 class UnavailableNetworkDataError extends WebDriverError { 910 constructor(obj, data = {}) { 911 super(obj, data); 912 this.status = "unavailable network data"; 913 } 914 } 915 916 /** 917 * A modal dialog was open, blocking this operation. 918 * 919 * @param {(string|Error)=} obj 920 * Optional string describing error situation or Error instance 921 * to propagate. 922 * @param {object=} data 923 * Additional error data helpful in diagnosing the error. 924 */ 925 class UnexpectedAlertOpenError extends WebDriverError { 926 constructor(obj, data = {}) { 927 super(obj, data); 928 this.status = "unexpected alert open"; 929 } 930 } 931 932 /** 933 * A command could not be executed because the remote end is not 934 * aware of it. 935 * 936 * @param {(string|Error)=} obj 937 * Optional string describing error situation or Error instance 938 * to propagate. 939 * @param {object=} data 940 * Additional error data helpful in diagnosing the error. 941 */ 942 class UnknownCommandError extends WebDriverError { 943 constructor(obj, data = {}) { 944 super(obj, data); 945 this.status = "unknown command"; 946 } 947 } 948 949 /** 950 * An unknown error occurred in the remote end while processing 951 * the command. 952 * 953 * @param {(string|Error)=} obj 954 * Optional string describing error situation or Error instance 955 * to propagate. 956 * @param {object=} data 957 * Additional error data helpful in diagnosing the error. 958 */ 959 class UnknownError extends WebDriverError { 960 constructor(obj, data = {}) { 961 super(obj, data); 962 this.status = "unknown error"; 963 } 964 } 965 966 /** 967 * Indicates that a command that should have executed properly 968 * cannot be supported for some reason. 969 * 970 * @param {(string|Error)=} obj 971 * Optional string describing error situation or Error instance 972 * to propagate. 973 * @param {object=} data 974 * Additional error data helpful in diagnosing the error. 975 */ 976 class UnsupportedOperationError extends WebDriverError { 977 constructor(obj, data = {}) { 978 super(obj, data); 979 this.status = "unsupported operation"; 980 } 981 } 982 983 const STATUSES = new Map([ 984 ["detached shadow root", DetachedShadowRootError], 985 ["element click intercepted", ElementClickInterceptedError], 986 ["element not accessible", ElementNotAccessibleError], 987 ["element not interactable", ElementNotInteractableError], 988 ["insecure certificate", InsecureCertificateError], 989 ["invalid argument", InvalidArgumentError], 990 ["invalid cookie domain", InvalidCookieDomainError], 991 ["invalid element state", InvalidElementStateError], 992 ["invalid selector", InvalidSelectorError], 993 ["invalid session id", InvalidSessionIDError], 994 ["invalid web extension", InvalidWebExtensionError], 995 ["javascript error", JavaScriptError], 996 ["move target out of bounds", MoveTargetOutOfBoundsError], 997 ["no such alert", NoSuchAlertError], 998 ["no such element", NoSuchElementError], 999 ["no such frame", NoSuchFrameError], 1000 ["no such handle", NoSuchHandleError], 1001 ["no such history entry", NoSuchHistoryEntryError], 1002 ["no such intercept", NoSuchInterceptError], 1003 ["no such network collector", NoSuchNetworkCollectorError], 1004 ["no such network data", NoSuchNetworkDataError], 1005 ["no such node", NoSuchNodeError], 1006 ["no such request", NoSuchRequestError], 1007 ["no such script", NoSuchScriptError], 1008 ["no such shadow root", NoSuchShadowRootError], 1009 ["no such user context", NoSuchUserContextError], 1010 ["no such web extension", NoSuchWebExtensionError], 1011 ["no such window", NoSuchWindowError], 1012 ["script timeout", ScriptTimeoutError], 1013 ["session not created", SessionNotCreatedError], 1014 ["stale element reference", StaleElementReferenceError], 1015 ["timeout", TimeoutError], 1016 ["unable to capture screen", UnableToCaptureScreen], 1017 ["unable to set cookie", UnableToSetCookieError], 1018 ["unable to set file input", UnableToSetFileInputError], 1019 ["unavailable network data", UnavailableNetworkDataError], 1020 ["unexpected alert open", UnexpectedAlertOpenError], 1021 ["unknown command", UnknownCommandError], 1022 ["unknown error", UnknownError], 1023 ["unsupported operation", UnsupportedOperationError], 1024 ["webdriver error", WebDriverError], 1025 ]); 1026 1027 // Errors must be exported as part of the `error` object. 1028 // We could declare each error as global variable, but because they are Error 1029 // prototypes this would mess up their names. 1030 for (let cls of STATUSES.values()) { 1031 error[cls.name] = cls; 1032 }