errors.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Avoid circular dependency on EventEmitter by implementing a subset of the interface.
  2. export class ErrorHandler {
  3. constructor() {
  4. this.listeners = [];
  5. this.unexpectedErrorHandler = function (e) {
  6. setTimeout(() => {
  7. if (e.stack) {
  8. throw new Error(e.message + '\n\n' + e.stack);
  9. }
  10. throw e;
  11. }, 0);
  12. };
  13. }
  14. emit(e) {
  15. this.listeners.forEach((listener) => {
  16. listener(e);
  17. });
  18. }
  19. onUnexpectedError(e) {
  20. this.unexpectedErrorHandler(e);
  21. this.emit(e);
  22. }
  23. // For external errors, we don't want the listeners to be called
  24. onUnexpectedExternalError(e) {
  25. this.unexpectedErrorHandler(e);
  26. }
  27. }
  28. export const errorHandler = new ErrorHandler();
  29. export function onUnexpectedError(e) {
  30. // ignore errors from cancelled promises
  31. if (!isPromiseCanceledError(e)) {
  32. errorHandler.onUnexpectedError(e);
  33. }
  34. return undefined;
  35. }
  36. export function onUnexpectedExternalError(e) {
  37. // ignore errors from cancelled promises
  38. if (!isPromiseCanceledError(e)) {
  39. errorHandler.onUnexpectedExternalError(e);
  40. }
  41. return undefined;
  42. }
  43. export function transformErrorForSerialization(error) {
  44. if (error instanceof Error) {
  45. let { name, message } = error;
  46. const stack = error.stacktrace || error.stack;
  47. return {
  48. $isError: true,
  49. name,
  50. message,
  51. stack
  52. };
  53. }
  54. // return as is
  55. return error;
  56. }
  57. const canceledName = 'Canceled';
  58. /**
  59. * Checks if the given error is a promise in canceled state
  60. */
  61. export function isPromiseCanceledError(error) {
  62. return error instanceof Error && error.name === canceledName && error.message === canceledName;
  63. }
  64. /**
  65. * Returns an error that signals cancellation.
  66. */
  67. export function canceled() {
  68. const error = new Error(canceledName);
  69. error.name = error.message;
  70. return error;
  71. }
  72. export function illegalArgument(name) {
  73. if (name) {
  74. return new Error(`Illegal argument: ${name}`);
  75. }
  76. else {
  77. return new Error('Illegal argument');
  78. }
  79. }
  80. export function illegalState(name) {
  81. if (name) {
  82. return new Error(`Illegal state: ${name}`);
  83. }
  84. else {
  85. return new Error('Illegal state');
  86. }
  87. }
  88. export class NotSupportedError extends Error {
  89. constructor(message) {
  90. super('NotSupported');
  91. if (message) {
  92. this.message = message;
  93. }
  94. }
  95. }