getsentry / sentry-javascript

Official Sentry SDKs for JavaScript
https://sentry.io
MIT License
7.87k stars 1.55k forks source link

All exceptions are logged into the console #13462

Closed RappyTV closed 1 week ago

RappyTV commented 2 weeks ago

Is there an existing issue for this?

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)
chargome commented 2 weeks ago

@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
});
RappyTV commented 2 weeks ago

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.

chargome commented 2 weeks ago

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

RappyTV commented 2 weeks ago

@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)

chargome commented 2 weeks ago

@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?

RappyTV commented 2 weeks ago

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);
chargome commented 2 weeks ago

@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.

RappyTV commented 2 weeks ago

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

andreiborza commented 2 weeks ago

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

RappyTV commented 2 weeks ago

Thank you guys!

andreiborza commented 2 weeks ago

@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

RappyTV commented 2 weeks ago

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

lforst commented 2 weeks ago

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.

RappyTV commented 2 weeks ago

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.