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

Missing stacktrace in renderer process when using Node.js API integration #308

Closed
6 of 7 tasks
clemp6r opened this issue Mar 8, 2021 · 6 comments · Fixed by #509
Closed
6 of 7 tasks

Missing stacktrace in renderer process when using Node.js API integration #308

clemp6r opened this issue Mar 8, 2021 · 6 comments · Fixed by #509

Comments

@clemp6r
Copy link

clemp6r commented Mar 8, 2021

Versions + Platform

  • SDK version - @sentry/electron@v2.4.0
  • Electron version - electron@v11.0.4
  • Platform - macOS

Description

When capturing a exception thrown by the Node integration in the renderer process, the reported stacktrace is empty.

Sample code to reproduce:

  const exec = promisify(childProcess.exec);
  const command = `commandThatFails`;
  let stdout: string;
  try {
    const response = await exec(command);
    stdout = response.stdout;
  } catch (error) {
    console.log('got error', error);
    stdout = error.stdout;
    if (!stdout) {
      Sentry.captureException(error);
    }
  }

The console prints the following (we can see here the value of error.stack):

got error Error: Command failed: commandThatFails
/bin/sh: commandThatFails: command not found

    at ChildProcess.exithandler (child_process.js:312)
    at ChildProcess.emit (events.js:315)
    at maybeClose (internal/child_process.js:1021)
    at Socket.<anonymous> (internal/child_process.js:443)
    at Socket.emit (events.js:315)
    at Pipe.<anonymous> (net.js:674)

The error is correctly reported when calling Sentry.captureException(error) but in the Sentry web interface the stacktrace is empty. Only the first two lines appear:

Command failed: commandThatFails
/bin/sh: commandThatFails: command not found

It seems the Sentry client tries to parse the stack as a Chrome stack, but as the error comes from the Node integration, the format does not match and all frames are skipped.

@timfish
Copy link
Collaborator

timfish commented Mar 9, 2021

Currently @sentry/node is used in the main process and @sentry/browser is used in the renderers.

If we can detect the difference between a Chrome exception and a nodejs exception, we might be able to call into @sentry/node in the browser. The main obstacle is the fact that @sentry/node currently makes use of nodejs functionality and this would need to be abstracted out.

I haven't looked into this for years, but I'm pretty sure Electron in its default configuration rethrows nodejs exceptions in the browser context. I think you might be able to stop that by subscribing to error events on process.

@clemp6r
Copy link
Author

clemp6r commented Mar 9, 2021

I'm pretty sure Electron in its default configuration rethrows nodejs exceptions in the browser context

Indeed, that's why I get a node-like stack in my renderer process, instead of a chrome-like stack object.

I think you might be able to stop that by subscribing to error events on process.

I don't understand, can you elaborate on this? What are we supposed to stop?

@timfish
Copy link
Collaborator

timfish commented Mar 9, 2021

You don't want to catch each exception twice. Once from nodejs, and once from Electron forwarding to Chrome.

I seem to remember that subscribing to the nodejs error events disables the re-throwing in the Chrome context.

@clemp6r
Copy link
Author

clemp6r commented Mar 9, 2021

You don't want to catch each exception twice

That's not what is happening. See my sample code: Node APIs are called from the renderer, and then an error is thrown and is caught a few lines below, in the renderer.

@timfish
Copy link
Collaborator

timfish commented Mar 9, 2021

Sorry, I haven't been very clear there!

I understand your issue and it is caused by the fact that @sentry/node is not used in the renderer.

I'm saying that to fix your issue, @sentry/electron needs to be modified to use @sentry/node in the renderer and we need to ensure that exceptions are not caught twice.

@clemp6r
Copy link
Author

clemp6r commented Mar 10, 2021

Besides, I looked again at my sample stacktrace and it seems there is nothing interesting into, it apart technical framework frames. No function from my application appear. I may have to create new Error objects if I want to have a good stracktrace. Or it is Sentry's responsiblity?

  try {
    const response = await exec(command);
  } catch (error) {
    console.log('got error', error);
    stdout = error.stdout;
    if (!stdout) {
      const wrappedError = new Error('Unable to run command: ' + error);
      Sentry.captureException(wrappedError);
    }
    ...

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

Successfully merging a pull request may close this issue.

2 participants