Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect error object serialization #4

Open
junajan opened this issue Jan 6, 2025 · 1 comment
Open

Incorrect error object serialization #4

junajan opened this issue Jan 6, 2025 · 1 comment

Comments

@junajan
Copy link

junajan commented Jan 6, 2025

Hi, we are using this package through discordjs package and in some occasions (during high memory load) we can see this error in our logs:

Error: Unhandled 'error' event emitted, received [object Object]
    at WebSocketShard.emit (/app/node_modules/@vladfrangu/async_event_emitter/dist/index.cjs:276:19)
    at WebSocketShard.onError (/app/node_modules/@discordjs/ws/dist/index.js:1070:10)
    at connection.onerror (/app/node_modules/@discordjs/ws/dist/index.js:683:12)
    at callListener (/app/node_modules/ws/lib/event-target.js:290:14)
    at WebSocket.onError (/app/node_modules/ws/lib/event-target.js:230:9)
    at WebSocket.emit (node:events:519:28)
    at emitErrorAndClose (/app/node_modules/ws/lib/websocket.js:1041:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

On file and line @vladfrangu/async_event_emitter/dist/index.cjs:276:19 there is this code:

const err = new Error(`Unhandled 'error' event emitted, received ${stringifiedError}`);

Which is part of this class method:

  emit(eventName, ...args) {
    let doError = eventName === "error";
    const events = this._events;
    if (events !== void 0) {
      doError = doError && "error" in events;
    } else if (!doError) {
      return false;
    }
    if (doError) {
      let er;
      if (args.length > 0) {
        er = args[0];
      }
      if (er instanceof Error) {
        try {
          const capture = {};
          Error.captureStackTrace(capture, _AsyncEventEmitter.prototype.emit);
          Object.defineProperty(er, "stack", {
            value: enhanceStackTrace.call(this, er, capture),
            configurable: true
          });
        } catch {
        }
        throw er;
      }
      const stringifiedError = String(er);
      const err = new Error(`Unhandled 'error' event emitted, received ${stringifiedError}`); // <-- log message gets created here
      err.context = er;
      throw err;
    }
    const handlers = events[eventName];
    if (handlers === void 0) {
      return false;
    }
    if (typeof handlers === "function") {
      const result = handlers.apply(this, args);
      if (result !== void 0 && result !== null) {
        handleMaybeAsync(this, result);
      }
    } else {
      const len = handlers.length;
      const listeners = arrayClone(handlers);
      for (let i = 0; i < len; ++i) {
        const result = listeners[i].apply(this, args);
        if (result !== void 0 && result !== null) {
          handleMaybeAsync(this, result);
        }
      }
    }
    return true;
  }

It looks like in cases when er variable is an object it gets incorrectly stringified into [object Object] which hides original error.
Maybe something like JSON.stringify(er) would be more suitable?

@vladfrangu
Copy link
Owner

Unless NodeJS changed how they emit this, I am not keen on drifting from their output, be it as useless as [object Object] 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants