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

Bun HTTP breaks Sentry Tracing #7472

Open
r614 opened this issue Dec 5, 2023 · 9 comments
Open

Bun HTTP breaks Sentry Tracing #7472

r614 opened this issue Dec 5, 2023 · 9 comments
Labels
bug Something isn't working needs investigate Needs to be investigated to find the root cause

Comments

@r614
Copy link

r614 commented Dec 5, 2023

What version of Bun is running?

1.0.7+b0393fba6200d8573f3433fb0af258a0e33ac157

What platform is your computer?

Darwin 23.1.0 arm64 arm

What steps can reproduce the bug?

Ref: getsentry/sentry-javascript#9564 and getsentry/sentry-javascript#9608

Code Sample

index.ts

import { uploadS3  } from "./files";
import * as Sentry from "@sentry/bun";

Sentry.init({
  dsn: <dsn>,
  tracesSampleRate: 1.0,
});

await uploadS3(
  "test",
  "/dev/backend/src/index.ts",
  "text/plain"
);

files.ts

import {
  S3Client,
} from "@aws-sdk/client-s3";
import * as Sentry from "@sentry/bun";
import { Upload } from "@aws-sdk/lib-storage";
import { createReadStream } from "node:fs";

const s3 = new S3Client({
  logger: console,
});

s3.middlewareStack.add((next) => async (args) => {
  console.log("s3 request", args);
  const result = await next(args);
  console.log("s3 response", result);
  return result;
});

const bucketName = <bucketName>

export const uploadS3 = async (
  fileId: string,
  fpath: string,
  mimeType: string
) => {
  console.log(
    "uploading file to S3",
    fileId,
    fpath,
    bucketName,
    mimeType,
  );
  try {
    const upload = new Upload({
      client: s3,
      params: {
        Bucket: bucketName,
        Key: fileId,
        Body: createReadStream(fpath),
      },
      queueSize: 4,
    });

    return upload.done();
  } catch (err) {
    console.error("error uploading file to S3", err);
    Sentry.captureException(err);
  }
};

package.json

{
  "name": "backend",
  "version": "1.0.50",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "bun run --watch src/index.ts"
  },
  "dependencies": {
    "@aws-sdk/client-s3": "^3.451.0",
    "@aws-sdk/lib-storage": "^3.454.0",
    "@sentry/bun": "^7.80.1",
  },
  "devDependencies": {
    "bun-types": "latest"
  },
  "module": "src/index.js"
}

What is the expected behavior?

File is uploaded to S3 successfully, action is logged to Sentry.

What do you see instead?

Request is never completed. It doesn't timeout either, just keeps the client waiting.
AFAIK I understand it, the S3 client doesn't even get a response so not sure if the file upload request is even sent.

Logs:

uploading file to S3 test /dev/backend/src/index.ts <bucketName> text/plain
s3 request {
  middlewareStack: {
    add: [Function: add],
    addRelativeTo: [Function: addRelativeTo],
    clone: [Function: clone],
    use: [Function: use],
    remove: [Function: remove],
    removeByTag: [Function: removeByTag],
    concat: [Function: concat],
    applyToStack: [Function: cloneTo],
    identify: [Function: identify],
    identifyOnResolve: [Function: identifyOnResolve],
    resolve: [Function: resolve]
  },
  input: {
    Bucket: <bucket>,
    Key: "test",
    Body: Buffer(2205) [ 105, 109, 112, 111, 114, 116, 32, 123, 32, 69, 108, 121, 115, 105, 97, 44, 32, 116, 32, 125, 32, 102, 114, 111, 109, 32, 34, 101, 108, 121, 115, 105, 97, 34, 59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 32, 99, 114, 101, 97, 116, 101, 65, 117, 116, 104, 48, 85, 115, 101, 114, 32, 125, 32, 102, 114, 111, 109, 32, 34, 46, 47, 109, 111, 100, 117, 108, 101, 115, 47, 97, 117, 116, 104, 48, 34, 59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 32, 103, 101, 116, 68, 114, 105, 118, 101, 67, 108, 105, 101, 110, 116, 44, 32, 117, 112, 108, 111, 97, 100, 70, 105, 108, 101, 84, 111, 71, 111, 111, 103, 108, 101, 68, 114, 105, 118, 101, 32, 125, 32, 102, 114, 111, 109, 32, 34, 46, 47, 109, 111, 100, 117, 108, 101, 115, 47, 103, 100, 114, 105, 118, 101, 34, 59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 32, 100, 111, 119, 110, 108, 111, 97, 100, 70, 105, 108, 101, 44, 32, 117, 112, 108, 111, 97, 100, 70, 105, 108, 101, 32, 125, 32, 102, 114, 111, 109, 32, 34, 46, 47, 109, 111, 100, 117, 108, 101, 115, 47, 102, 105, 108, 101, 115, 34, 59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 32, 105, 115, 73, 110, 116, 101, 114, 110, 97, 108, 65, 112, 112, 32, 125, 32, 102, 114, 111, 109, 32, 34, 46, 47, 109, 111, 100, 117, 108, 101, 115, 47, 109, 105, 100, 100, 108, 101, 119, 97, 114, 101, 34, 59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 32, 115, 119, 97, 103, 103, 101, 114, 32, 125, 32, 102, 114, 111, 109, 32, 34, 64, 101, 108, 121, 115, 105, 97, 106, 115, 47, 115, 119, 97, 103, 103, 101, 114, 34, 59, 10, 105, 109, 112, 111, 114, 116, 32, 42, 32, 97, 115, 32, 83, 101, 110, 116, 114, 121, 32, 102, 114, 111, 109, 32, 34, 64, 115, 101, 110, 116, 114, 121, 47, 98, 117, 110, 34, 59, 10, 105, 109, 112, 111, 114, 116, 32, 123, 32, 99, 111, 114, 115, 32, 125, 32, 102, 114, 111, 109, 32, 34, 64, 101, 108, 121, 115, 105, 97, 106, 115, 47, 99, 111, 114, 115, 34, 59, 10, 10, 105, 102, 32, 40, 112, 114, 111, 99, 101, 115, 115, 46, 101, 110, 118, 46, 78, 79, 68, 69, 95, 69, 78, 86, 32, 61, 61, 61, 32, 34, 112, 114, 111, 100, 117, 99, 116, 105, 111, 110, 34, 41, 32, 123, 10, 32, 32, 83, 101, 110, 116, 114, 121, 46, 105, 110, 105, 116, 40, 123, 10, 32, 32, 32, 32, 100, 115, 110, 58, 32, 34, 104, 116, 116, 112, 115, 58, 47, 47, 52, 99, 102, 52, 98, 102, 53, 51, 57, 53, 51, 57, 56, 101, 97, 97, 56, 100, 54, 49, 98, 99, 51, 97, 102, 98, 54, 53, 53, 54, 52, 49, 64, ... 1692 more ]
  }
}
endpoints Initial EndpointParams: {
  "Bucket": <bucket>,
  "ForcePathStyle": false,
  "UseArnRegion": false,
  "DisableMultiRegionAccessPoints": false,
  "Accelerate": false,
  "UseGlobalEndpoint": false,
  "UseFIPS": false,
  "Region": "us-west-2",
  "UseDualStack": false
}
endpoints evaluateCondition: isSet($Region) = true
endpoints evaluateCondition: booleanEquals($Accelerate, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: booleanEquals($UseFIPS, true) = false
endpoints evaluateCondition: isSet($Bucket) = true
endpoints evaluateCondition: substring($Bucket, 49, 50, true) = null
endpoints evaluateCondition: isSet($Bucket) = true
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: booleanEquals($ForcePathStyle, false) = true
endpoints evaluateCondition: aws.isVirtualHostableS3Bucket($Bucket, false) = true
endpoints evaluateCondition: aws.partition($Region) = {
  "dnsSuffix": "amazonaws.com",
  "dualStackDnsSuffix": "api.aws",
  "implicitGlobalRegion": "us-east-1",
  "name": "aws",
  "supportsDualStack": true,
  "supportsFIPS": true,
  "description": "US West (Oregon)"
}
endpoints assign: partitionResult := {
  "dnsSuffix": "amazonaws.com",
  "dualStackDnsSuffix": "api.aws",
  "implicitGlobalRegion": "us-east-1",
  "name": "aws",
  "supportsDualStack": true,
  "supportsFIPS": true,
  "description": "US West (Oregon)"
}
endpoints evaluateCondition: isValidHostLabel($Region, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: isSet($Endpoint) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: not(isSet($Endpoint)) = true
endpoints evaluateCondition: stringEquals($Region, aws-global) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: not(isSet($Endpoint)) = true
endpoints evaluateCondition: not(stringEquals($Region, aws-global)) = true
endpoints evaluateCondition: booleanEquals($UseGlobalEndpoint, true) = false
endpoints evaluateCondition: booleanEquals($UseDualStack, false) = true
endpoints evaluateCondition: booleanEquals($UseFIPS, false) = true
endpoints evaluateCondition: booleanEquals($Accelerate, false) = true
endpoints evaluateCondition: not(isSet($Endpoint)) = true
endpoints evaluateCondition: not(stringEquals($Region, aws-global)) = true
endpoints evaluateCondition: booleanEquals($UseGlobalEndpoint, false) = true
endpoints Resolving endpoint from template: {
  "url": "https://{Bucket}.s3.{Region}.{partitionResult#dnsSuffix}",
  "properties": {
    "authSchemes": [
      {
        "disableDoubleEncoding": true,
        "name": "sigv4",
        "signingName": "s3",
        "signingRegion": "{Region}"
      }
    ]
  },
  "headers": {}
}
endpoints Resolved endpoint: {
  "headers": {},
  "properties": {
    "authSchemes": [
      {
        "disableDoubleEncoding": true,
        "name": "sigv4",
        "signingName": "s3",
        "signingRegion": "us-west-2"
      }
    ]
  },
  "url": "https://<bucket>.s3.us-west-2.amazonaws.com/"
}

Additional information

Seems like a Bun issue from getsentry/sentry-javascript#9564 (comment)
Removing the HTTP integration from Sentry fixes the issue for now, but we lose some logs we really need

Sentry.init({
  dsn: <dsn>,
  tracesSampleRate: 1.0,
  debug: true,
  integrations: (int) =>
    int.filter((i) => !["Http"].includes(i.name)),
});
@r614 r614 added the bug Something isn't working label Dec 5, 2023
@Electroid Electroid added the needs investigate Needs to be investigated to find the root cause label Dec 5, 2023
@approached
Copy link

Here is the problem: #5091

@colinricardo
Copy link

colinricardo commented Jan 15, 2024

experiencing this also with:

  • @sentry/bun version 7.93.0
  • bun version 1.0.20

@HazAT
Copy link

HazAT commented Jan 16, 2024

Can I ask, is this an issue with the Sentry SDK, like does it work if you remove/disable Sentry?

@lsnow99
Copy link

lsnow99 commented Jan 21, 2024

Can I ask, is this an issue with the Sentry SDK, like does it work if you remove/disable Sentry?

Disabling sentry fixes the issue for me (commenting out Sentry.init or adding this line to the Sentry.init config object: integrations: (int) => int.filter((i) => !["BunServer", "Http"].includes(i.name)), - as shown in the original issue)

The response on the relevant sentry issue was that since their monkey patching works for node that this must be an issue with bun

@opensourceinterfaces292
Copy link

Hello! Thanks for all of your hard work. @Jarred-Sumner I think lots of teams are eager to move to Bun but can't due this issue, do you know when we can expect a fix for this? 🥲 Thanks again!

@AbhiPrasad
Copy link
Contributor

We changed how we do monkeypatching of HTTP in our upcoming new Sentry JavaScript SDKs major version, 8.0.

Currently there is a beta release: https://github.com/getsentry/sentry-javascript/releases/tag/8.0.0-beta.1

This means you can use Sentry with the v8 beta and tracing should work with Bun!

@AbhiPrasad
Copy link
Contributor

@rhuanbarreto
Copy link

@AbhiPrasad Does this use the latest changes from v1.1.8?

@AbhiPrasad
Copy link
Contributor

@AbhiPrasad Does this use the latest changes from v1.1.8?

Yes!

PR here: getsentry/sentry-javascript#11960

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs investigate Needs to be investigated to find the root cause
Projects
None yet
Development

No branches or pull requests

9 participants