sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

All exceptions are logged into the console

Open RappyTV opened this issue 1 year ago • 10 comments

Is there an existing issue for this?

  • [x] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
  • [x] I have reviewed the documentation https://docs.sentry.io/
  • [x] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases

How do you use Sentry?

Self-hosted/on-premise

Which SDK are you using?

@sentry/bun

SDK Version

8.26.0

Framework Version

No response

Link to Sentry event

No response

Reproduction Example/SDK Setup

Logger.info('Initializing Sentry...');
const client = new Sentry.BunClient({
    dsn,
    tracesSampleRate: 1.0,
    stackParser: Sentry.defaultStackParser,
    transport: Sentry.makeFetchTransport,
    integrations: Sentry.getDefaultIntegrations({}).filter((integration) => integration.name !== 'Http'),
    release: version
});

Sentry.setCurrentClient(client);
client.init();
Logger.info('Initialized Sentry!');

Steps to Reproduce

  1. Initialize sentry
  2. Throw any exception

Expected Result

I receive my own exception handler log:

[ERROR] Unhandled rejection: "TypeError: test error"

Actual Result

I receive my own log + a log which I don't want and seemingly can't disable:

[ERROR] Unhandled rejection: "TypeError: test error" 
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
TypeError: test error
    at fire (D:\windirs\Dokumente\@Coding\Javascript\Discord\Bots\Romy Related\boosts\src\events\Ready.ts:25:19)
    at <anonymous> (node:events:33:26)
    at emit2 (node:events:211:45)
    at triggerClientReady (D:\windirs\Dokumente\@Coding\Javascript\Discord\Bots\Romy Related\boosts\node_modules\discord.js\src\client\websocket\WebSocketManager.js:388:17)
    at checkShardsReady (D:\windirs\Dokumente\@Coding\Javascript\Discord\Bots\Romy Related\boosts\node_modules\discord.js\src\client\websocket\WebSocketManager.js:371:10)
    at <anonymous> (D:\windirs\Dokumente\@Coding\Javascript\Discord\Bots\Romy Related\boosts\node_modules\discord.js\src\client\websocket\WebSocketManager.js:201:16)
    at emit (node:events:180:48)
    at checkReady (D:\windirs\Dokumente\@Coding\Javascript\Discord\Bots\Romy Related\boosts\node_modules\discord.js\src\client\websocket\WebSocketShard.js:181:12)
    at gotGuild (D:\windirs\Dokumente\@Coding\Javascript\Discord\Bots\Romy Related\boosts\node_modules\discord.js\src\client\websocket\WebSocketShard.js:155:10)
    at <anonymous> (D:\windirs\Dokumente\@Coding\Javascript\Discord\Bots\Romy Related\boosts\node_modules\discord.js\src\client\websocket\WebSocketManager.js:241:15)

RappyTV avatar Aug 26 '24 15:08 RappyTV

@RappyTV

I'm not sure what your exact issue is and how it is Sentry related. You receive logs for unhandled errors?

Also, you can simplify your init like this:

const client = Sentry.init({
    dsn,
    tracesSampleRate: 1.0,
    integrations: Sentry.getDefaultIntegrations({}).filter((integration) => integration.name !== 'Http'),
    release: version
});

chargome avatar Aug 27 '24 07:08 chargome

Hey @chargome! The simplification does not work because it's a workaround for issue #12891.

Now to clarify my problem: I have a custom exception/rejection handler which prevents crashes and logs the errors to the console. But as soon as I initialize sentry, the complete exceptions are also being logged (Which doesn't happen if I don't initialize Sentry). So it has to be a problem with this wrapper I suppose. I just want my log to look clean but those big exceptions just make it look bad, especially as they're logged in a prettier format before the unwanted Sentry log.

RappyTV avatar Aug 27 '24 11:08 RappyTV

@RappyTV can you paste a snippet of your custom exception handler?

chargome avatar Aug 27 '24 11:08 chargome

@chargome Sure!

import Logger from "./Logger";
import { captureException } from "@sentry/bun";
import { sentry } from "../../config.json";

export default function handleErrors() {
    Logger.debug(`Exception handler initialized.`);
    process.on('unhandledRejection', (reason) => {
        Logger.error(`Unhandled rejection: "${reason}"`);
        if(sentry.enabled) captureException(reason);
    });
    process.on('uncaughtException', (error) => {
        Logger.error(`Unhandled exception: "${error}"`);
        if(sentry.enabled) captureException(error);
    });
}

(Also the issue still occurs even if I comment-out the captureException lines)

RappyTV avatar Aug 27 '24 11:08 RappyTV

@RappyTV Hm still can't reproduce it with that code, do you do anything with the error in the Logger? Also, where do you call that handleErrors function?

chargome avatar Aug 27 '24 11:08 chargome

The Logger.ts looks like this:

import chalk from "chalk";
import { logLevel } from "../../config.json";

enum LogLevel {
    Error,
    Warn,
    Info,
    Debug
}

export default class Logger {
    public static debug(text: any, ...options: any[]) {
        if(LogLevel.Debug > Logger.getLoglevel()) return;
        console.log(chalk.blueBright(`[DEBUG]`), text, options.join(' '));
    }

    public static info(text: any, ...options: any[]) {
        if(LogLevel.Info > Logger.getLoglevel()) return;
        console.log(chalk.blue(`[INFO]`), text, options.join(' '));
    }

    public static warn(text: any, ...options: any[]) {
        if(LogLevel.Warn > Logger.getLoglevel()) return;
        console.log(chalk.yellow(`[WARN]`), text, options.join(' '));
    }

    public static error(text: any, ...options: any[]) {
        if(LogLevel.Error > Logger.getLoglevel()) return;
        console.log(chalk.red(`[ERROR]`), text, options.join(' '));
    }

    public static getLoglevel(): LogLevel {
        return LogLevel[logLevel as keyof typeof LogLevel] || LogLevel.Info;
    }
}

so that's probably not it. I'm calling the handleErrors function right before the initializeSentry function in my index.ts

import { initializeSentry } from "./util/Sentry";
import handleErrors from "./util/ErrorHandler";

handleErrors();
if(config.sentry.enabled) initializeSentry(config.sentry.dsn);

RappyTV avatar Aug 27 '24 11:08 RappyTV

@RappyTV

Seems that the issue is somewhere else still. Would you mind to create a small reproducible repo / stackblitz, this would help to fix your issue more efficiently.

chargome avatar Aug 27 '24 12:08 chargome

As it's a private repository and I don't really plan on making it public I would provide you a zip download link. The link expires in 3 days https://media.rappytv.com/u/2VVgNF.zip

RappyTV avatar Aug 27 '24 14:08 RappyTV

Thanks for the submission. I'll take a look at it too.

andreiborza avatar Aug 28 '24 07:08 andreiborza

Thank you guys!

RappyTV avatar Aug 28 '24 12:08 RappyTV

@RappyTV need some instructions on how to run your app :) please provide a valid config.json, you could send me a mail at my github firstname dot lastname and @sentry.io

andreiborza avatar Aug 29 '24 14:08 andreiborza

@andreiborza Alr I sent you an email. Thanks for your help :D

RappyTV avatar Aug 29 '24 14:08 RappyTV

Hi, I think I understand what is happening. Our onUnhandledRejectionIntegration catches errors to report them and is simulating Node.js' native exit behaviour:

https://github.com/getsentry/sentry-javascript/blob/eacf56b0994a6d061452280d7d338502a8e1ff32/packages/node/src/integrations/onunhandledrejection.ts#L82-L93

Thereby it is logging the rejection and this is what may cause the error to appear in your logs.

You can disable this by doing:

Sentry.init({
  integrations: [Sentry.onUnhandledRejectionIntegration({ mode: 'none' })]
})

However, when your application throws unhandled promise rejections, they will not be reported that way. You can fix this by manually registering a process.on('unhandledRejection') handler and doing a Sentry.captureException(e) in there.

lforst avatar Aug 30 '24 09:08 lforst

Hey thanks a lot, that did in fact work. Just a little info because you said that I need to use my own handler for unhandled rejections (Which also was my intention in the first place): The exceptions/rejections are being reported to my sentry instance anyways even without my custom handler. You might wanna look into that if you didn't expect that behavior. But I don't have any problems anymore so feel free to close the issue.

RappyTV avatar Aug 30 '24 17:08 RappyTV