diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index cf09758f..4e817807 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -44,21 +44,21 @@ jobs: uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3.14.1 with: apiToken: ${{ secrets.CF_API_TOKEN }} - command: deploy --env staging --outdir=./dist - - - name: Upload sourcemaps for dist-worker-staging - if: github.event_name == 'push' - env: - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - run: | - npx sentry-cli sourcemaps inject --org nodejs --project dist-worker-staging ./dist && npx sentry-cli sourcemaps upload --org nodejs --project dist-worker-staging ./dist + command: deploy --env staging --outdir=./dist --upload-source-maps --var SENTRY_RELEASE:$(npx sentry-cli releases propose-version) - name: Deploy to Production if: github.event_name == 'workflow_dispatch' uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3.14.1 with: apiToken: ${{ secrets.CF_API_TOKEN }} - command: deploy --env prod --outdir=./dist + command: deploy --env prod --outdir=./dist --upload-source-maps --var SENTRY_RELEASE:$(npx sentry-cli releases propose-version) + + - name: Upload Source Maps to Sentry + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: nodejs-org + SENTRY_PROJECT: ${{ (github.event_name == 'workflow_dispatch' && 'dist-worker-prod') || 'dist-worker-staging' }} + run: ./scripts/upload-sourcemaps.sh - name: Alert on Failure if: failure() && github.repository == 'nodejs/release-cloudflare-worker' diff --git a/package-lock.json b/package-lock.json index 7747556b..4058fd1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,16 +9,16 @@ "version": "0.0.0", "dependencies": { "@aws-sdk/client-s3": "^3.859.0", + "@sentry/cloudflare": "^10.37.0", "itty-router": "^5.0.22", - "mustache": "^4.2.0", - "toucan-js": "^4.1.1" + "mustache": "^4.2.0" }, "devDependencies": { "@cloudflare/vitest-pool-workers": "^0.10.1", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "^9.39.1", "@reporters/github": "^1.7.2", - "@sentry/cli": "^2.58.2", + "@sentry/cli": "^2.58.4", "@types/mustache": "^4.2.6", "@types/node": "^25.0.3", "@typescript-eslint/eslint-plugin": "^8.52.0", @@ -988,7 +988,6 @@ "integrity": "sha512-Wj7/AMtE9MRnAXa6Su3Lk0LNCfqDYgfwVjwRFVum9U7wsto1imuHqk4kTm7Jni+5A0Hn7dttL6O/zjvUvoo+8A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "defu": "^6.1.4", "exsolve": "^1.0.7", @@ -2262,6 +2261,15 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@pkgr/core": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.7.tgz", @@ -2622,12 +2630,12 @@ ] }, "node_modules/@sentry/cli": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.58.2.tgz", - "integrity": "sha512-U4u62V4vaTWF+o40Mih8aOpQKqKUbZQt9A3LorIJwaE3tO3XFLRI70eWtW2se1Qmy0RZ74zB14nYcFNFl2t4Rw==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.58.4.tgz", + "integrity": "sha512-ArDrpuS8JtDYEvwGleVE+FgR+qHaOp77IgdGSacz6SZy6Lv90uX0Nu4UrHCQJz8/xwIcNxSqnN22lq0dH4IqTg==", "dev": true, "hasInstallScript": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "dependencies": { "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.7", @@ -2642,22 +2650,22 @@ "node": ">= 10" }, "optionalDependencies": { - "@sentry/cli-darwin": "2.58.2", - "@sentry/cli-linux-arm": "2.58.2", - "@sentry/cli-linux-arm64": "2.58.2", - "@sentry/cli-linux-i686": "2.58.2", - "@sentry/cli-linux-x64": "2.58.2", - "@sentry/cli-win32-arm64": "2.58.2", - "@sentry/cli-win32-i686": "2.58.2", - "@sentry/cli-win32-x64": "2.58.2" + "@sentry/cli-darwin": "2.58.4", + "@sentry/cli-linux-arm": "2.58.4", + "@sentry/cli-linux-arm64": "2.58.4", + "@sentry/cli-linux-i686": "2.58.4", + "@sentry/cli-linux-x64": "2.58.4", + "@sentry/cli-win32-arm64": "2.58.4", + "@sentry/cli-win32-i686": "2.58.4", + "@sentry/cli-win32-x64": "2.58.4" } }, "node_modules/@sentry/cli-darwin": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.58.2.tgz", - "integrity": "sha512-MArsb3zLhA2/cbd4rTm09SmTpnEuZCoZOpuZYkrpDw1qzBVJmRFA1W1hGAQ9puzBIk/ubY3EUhhzuU3zN2uD6w==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.58.4.tgz", + "integrity": "sha512-kbTD+P4X8O+nsNwPxCywtj3q22ecyRHWff98rdcmtRrvwz8CKi/T4Jxn/fnn2i4VEchy08OWBuZAqaA5Kh2hRQ==", "dev": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "optional": true, "os": [ "darwin" @@ -2667,14 +2675,14 @@ } }, "node_modules/@sentry/cli-linux-arm": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.58.2.tgz", - "integrity": "sha512-HU9lTCzcHqCz/7Mt5n+cv+nFuJdc1hGD2h35Uo92GgxX3/IujNvOUfF+nMX9j6BXH6hUt73R5c0Ycq9+a3Parg==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.58.4.tgz", + "integrity": "sha512-rdQ8beTwnN48hv7iV7e7ZKucPec5NJkRdrrycMJMZlzGBPi56LqnclgsHySJ6Kfq506A2MNuQnKGaf/sBC9REA==", "cpu": [ "arm" ], "dev": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "optional": true, "os": [ "linux", @@ -2686,14 +2694,14 @@ } }, "node_modules/@sentry/cli-linux-arm64": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.58.2.tgz", - "integrity": "sha512-ay3OeObnbbPrt45cjeUyQjsx5ain1laj1tRszWj37NkKu55NZSp4QCg1gGBZ0gBGhckI9nInEsmKtix00alw2g==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.58.4.tgz", + "integrity": "sha512-0g0KwsOozkLtzN8/0+oMZoOuQ0o7W6O+hx+ydVU1bktaMGKEJLMAWxOQNjsh1TcBbNIXVOKM/I8l0ROhaAb8Ig==", "cpu": [ "arm64" ], "dev": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "optional": true, "os": [ "linux", @@ -2705,15 +2713,15 @@ } }, "node_modules/@sentry/cli-linux-i686": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.58.2.tgz", - "integrity": "sha512-CN9p0nfDFsAT1tTGBbzOUGkIllwS3hygOUyTK7LIm9z+UHw5uNgNVqdM/3Vg+02ymjkjISNB3/+mqEM5osGXdA==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.58.4.tgz", + "integrity": "sha512-NseoIQAFtkziHyjZNPTu1Gm1opeQHt7Wm1LbLrGWVIRvUOzlslO9/8i6wETUZ6TjlQxBVRgd3Q0lRBG2A8rFYA==", "cpu": [ "x86", "ia32" ], "dev": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "optional": true, "os": [ "linux", @@ -2725,14 +2733,14 @@ } }, "node_modules/@sentry/cli-linux-x64": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.58.2.tgz", - "integrity": "sha512-oX/LLfvWaJO50oBVOn4ZvG2SDWPq0MN8SV9eg5tt2nviq+Ryltfr7Rtoo+HfV+eyOlx1/ZXhq9Wm7OT3cQuz+A==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.58.4.tgz", + "integrity": "sha512-d3Arz+OO/wJYTqCYlSN3Ktm+W8rynQ/IMtSZLK8nu0ryh5mJOh+9XlXY6oDXw4YlsM8qCRrNquR8iEI1Y/IH+Q==", "cpu": [ "x64" ], "dev": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "optional": true, "os": [ "linux", @@ -2744,14 +2752,14 @@ } }, "node_modules/@sentry/cli-win32-arm64": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.58.2.tgz", - "integrity": "sha512-+cl3x2HPVMpoSVGVM1IDWlAEREZrrVQj4xBb0TRKII7g3hUxRsAIcsrr7+tSkie++0FuH4go/b5fGAv51OEF3w==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.58.4.tgz", + "integrity": "sha512-bqYrF43+jXdDBh0f8HIJU3tbvlOFtGyRjHB8AoRuMQv9TEDUfENZyCelhdjA+KwDKYl48R1Yasb4EHNzsoO83w==", "cpu": [ "arm64" ], "dev": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "optional": true, "os": [ "win32" @@ -2761,15 +2769,15 @@ } }, "node_modules/@sentry/cli-win32-i686": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.58.2.tgz", - "integrity": "sha512-omFVr0FhzJ8oTJSg1Kf+gjLgzpYklY0XPfLxZ5iiMiYUKwF5uo1RJRdkUOiEAv0IqpUKnmKcmVCLaDxsWclB7Q==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.58.4.tgz", + "integrity": "sha512-3triFD6jyvhVcXOmGyttf+deKZcC1tURdhnmDUIBkiDPJKGT/N5xa4qAtHJlAB/h8L9jgYih9bvJnvvFVM7yug==", "cpu": [ "x86", "ia32" ], "dev": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "optional": true, "os": [ "win32" @@ -2779,14 +2787,14 @@ } }, "node_modules/@sentry/cli-win32-x64": { - "version": "2.58.2", - "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.58.2.tgz", - "integrity": "sha512-2NAFs9UxVbRztQbgJSP5i8TB9eJQ7xraciwj/93djrSMHSEbJ0vC47TME0iifgvhlHMs5vqETOKJtfbbpQAQFA==", + "version": "2.58.4", + "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.58.4.tgz", + "integrity": "sha512-cSzN4PjM1RsCZ4pxMjI0VI7yNCkxiJ5jmWncyiwHXGiXrV1eXYdQ3n1LhUYLZ91CafyprR0OhDcE+RVZ26Qb5w==", "cpu": [ "x64" ], "dev": true, - "license": "BSD-3-Clause", + "license": "FSL-1.1-MIT", "optional": true, "os": [ "win32" @@ -2795,38 +2803,34 @@ "node": ">=10" } }, - "node_modules/@sentry/core": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.9.2.tgz", - "integrity": "sha512-ixm8NISFlPlEo3FjSaqmq4nnd13BRHoafwJ5MG+okCz6BKGZ1SexEggP42/QpGvDprUUHnfncG6WUMgcarr1zA==", + "node_modules/@sentry/cloudflare": { + "version": "10.37.0", + "resolved": "https://registry.npmjs.org/@sentry/cloudflare/-/cloudflare-10.37.0.tgz", + "integrity": "sha512-js7HYsTGsYK/+uJyLc3yMruQ1tiprMXBQGjUs/m/a4H5V68GqQcus/XbQF0YJS/RqeFuAHAoVSS5D49AUGT12g==", "license": "MIT", "dependencies": { - "@sentry/types": "8.9.2", - "@sentry/utils": "8.9.2" + "@opentelemetry/api": "^1.9.0", + "@sentry/core": "10.37.0" }, "engines": { - "node": ">=14.18" - } - }, - "node_modules/@sentry/types": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.9.2.tgz", - "integrity": "sha512-+LFOyQGl+zk5SZRGZD2MEURf7i5RHgP/mt3s85Rza+vz8M211WJ0YsjkIGUJFSY842nged5QLx4JysLaBlLymg==", - "license": "MIT", - "engines": { - "node": ">=14.18" + "node": ">=18" + }, + "peerDependencies": { + "@cloudflare/workers-types": "^4.x" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + } } }, - "node_modules/@sentry/utils": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.9.2.tgz", - "integrity": "sha512-A4srR9mEBFdVXwSEKjQ94msUbVkMr8JeFiEj9ouOFORw/Y/ux/WV2bWVD/ZI9wq0TcTNK8L1wBgU8UMS5lIq3A==", + "node_modules/@sentry/core": { + "version": "10.37.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.37.0.tgz", + "integrity": "sha512-hkRz7S4gkKLgPf+p3XgVjVm7tAfvcEPZxeACCC6jmoeKhGkzN44nXwLiqqshJ25RMcSrhfFvJa/FlBg6zupz7g==", "license": "MIT", - "dependencies": { - "@sentry/types": "8.9.2" - }, "engines": { - "node": ">=14.18" + "node": ">=18" } }, "node_modules/@sindresorhus/is": { @@ -3623,7 +3627,6 @@ "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -3678,7 +3681,6 @@ "integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.52.0", "@typescript-eslint/types": "8.52.0", @@ -3966,7 +3968,6 @@ "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/utils": "3.2.4", "pathe": "^2.0.3", @@ -3982,7 +3983,6 @@ "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", @@ -4025,7 +4025,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4510,7 +4509,6 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4571,7 +4569,6 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -5612,7 +5609,6 @@ "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -6144,7 +6140,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -6182,17 +6177,6 @@ "node": ">=14.0.0" } }, - "node_modules/toucan-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/toucan-js/-/toucan-js-4.1.1.tgz", - "integrity": "sha512-GTPwEaCRN8IbYe5/VeGiwxYvMO0dKaC16fTeLbF+QGswjkLZ9JUqAfDhLMyH2SWukYhmetH+uxWa1Bhluv/evQ==", - "license": "MIT", - "dependencies": { - "@sentry/core": "8.9.2", - "@sentry/types": "8.9.2", - "@sentry/utils": "8.9.2" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -6225,7 +6209,6 @@ "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" @@ -6267,7 +6250,6 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6306,7 +6288,6 @@ "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "pathe": "^2.0.3" } @@ -6335,7 +6316,6 @@ "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -6452,7 +6432,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -6466,7 +6445,6 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", @@ -6604,7 +6582,6 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "bin": { "workerd": "bin/workerd" }, @@ -6789,7 +6766,6 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "bin": { "workerd": "bin/workerd" }, diff --git a/package.json b/package.json index a6d512b2..4c18f88b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@eslint/eslintrc": "^3.2.0", "@eslint/js": "^9.39.1", "@reporters/github": "^1.7.2", - "@sentry/cli": "^2.58.2", + "@sentry/cli": "^2.58.4", "@types/mustache": "^4.2.6", "@types/node": "^25.0.3", "@typescript-eslint/eslint-plugin": "^8.52.0", @@ -38,8 +38,8 @@ }, "dependencies": { "@aws-sdk/client-s3": "^3.859.0", + "@sentry/cloudflare": "^10.37.0", "itty-router": "^5.0.22", - "mustache": "^4.2.0", - "toucan-js": "^4.1.1" + "mustache": "^4.2.0" } } diff --git a/scripts/upload-sourcemaps.sh b/scripts/upload-sourcemaps.sh new file mode 100755 index 00000000..a4844f05 --- /dev/null +++ b/scripts/upload-sourcemaps.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Uploads a build's sourcemaps to Sentry so we can get a usable stacktrace when +# errors happen. + +if [ -x "X$SENTRY_ORG" = "X" ]; then + echo "SENTRY_ORG missing" + exit 1 +fi + +if [ -x "X$SENTRY_PROJECT" = "X" ]; then + echo "SENTRY_PROJECT missing" + exit 1 +fi + +SENTRY_RELEASE=$(npx sentry-cli releases propose-version) + +echo Creating release $SENTRY_RELEASE + +npx sentry-cli releases new $SENTRY_RELEASE + --org=$SENTRY_ORG + --project=$SENTRY_PROJECT + +npx sentry-cli sourcemaps upload \ + --org=$SENTRY_ORG \ + --project=$SENTRY_PROJECT \ + --release=$SENTRY_RELEASE \ + --strip-prefix 'dist/..' dist diff --git a/src/context.ts b/src/context.ts index 5cbf9abc..43def112 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,8 +1,6 @@ -import type { Toucan } from 'toucan-js'; import type { Env } from './env'; export interface Context { env: Env; execution: ExecutionContext; - sentry?: Toucan; } diff --git a/src/middleware/cacheMiddleware.ts b/src/middleware/cacheMiddleware.ts index 1133a811..9df502c5 100644 --- a/src/middleware/cacheMiddleware.ts +++ b/src/middleware/cacheMiddleware.ts @@ -1,3 +1,4 @@ +import * as Sentry from '@sentry/cloudflare'; import type { Middleware } from './middleware'; /** @@ -22,7 +23,7 @@ export function cached(middleware: Middleware): Middleware { const wrapper: Middleware = { async handle(request, ctx) { - ctx.sentry?.addBreadcrumb({ + Sentry.addBreadcrumb({ category: 'CacheMiddleware', data: { underlyingMiddleware: middleware.constructor.name, diff --git a/src/middleware/notFoundMiddleware.ts b/src/middleware/notFoundMiddleware.ts index 5b841860..5fc301ba 100644 --- a/src/middleware/notFoundMiddleware.ts +++ b/src/middleware/notFoundMiddleware.ts @@ -1,11 +1,11 @@ -import type { Context } from '../context'; +import * as Sentry from '@sentry/cloudflare'; import responses from '../responses'; import type { Request } from '../routes/request'; import type { Middleware } from './middleware'; export class NotFoundMiddleware implements Middleware { - handle(request: Request, ctx: Context): Promise { - ctx.sentry.addBreadcrumb({ + handle(request: Request): Promise { + Sentry.addBreadcrumb({ category: 'NotFoundMiddleware', message: 'hit', }); diff --git a/src/middleware/optionsMiddleware.ts b/src/middleware/optionsMiddleware.ts index 2f849992..741128a9 100644 --- a/src/middleware/optionsMiddleware.ts +++ b/src/middleware/optionsMiddleware.ts @@ -1,13 +1,13 @@ +import * as Sentry from '@sentry/cloudflare'; import { CACHE_HEADERS } from '../constants/cache'; -import type { Context } from '../context'; import type { Middleware } from './middleware'; /** * Handles OPTION requests, just returns what HTTP methods we support */ export class OptionsMiddleware implements Middleware { - handle(_: Request, ctx: Context): Promise { - ctx.sentry.addBreadcrumb({ + handle(_: Request): Promise { + Sentry.addBreadcrumb({ category: 'OptionsMiddleware', message: 'hit', }); diff --git a/src/middleware/originMiddleware.ts b/src/middleware/originMiddleware.ts index a01e03cb..1d09803d 100644 --- a/src/middleware/originMiddleware.ts +++ b/src/middleware/originMiddleware.ts @@ -1,3 +1,4 @@ +import * as Sentry from '@sentry/cloudflare'; import { CACHE_HEADERS } from '../constants/cache'; import type { Context } from '../context'; import type { Request } from '../routes/request'; @@ -13,7 +14,7 @@ import type { Middleware } from './middleware'; */ export class OriginMiddleware implements Middleware { async handle(request: Request, ctx: Context): Promise { - ctx.sentry.addBreadcrumb({ + Sentry.addBreadcrumb({ category: 'OriginMiddleware', message: 'hit', }); diff --git a/src/middleware/r2Middleware.ts b/src/middleware/r2Middleware.ts index 67962f95..7322207d 100644 --- a/src/middleware/r2Middleware.ts +++ b/src/middleware/r2Middleware.ts @@ -1,3 +1,4 @@ +import * as Sentry from '@sentry/cloudflare'; import { CACHE_HEADERS } from '../constants/cache'; import docsDirectory from '../constants/docsDirectory.json' assert { type: 'json' }; import type { Context } from '../context'; @@ -19,7 +20,7 @@ export class R2Middleware implements Middleware { const path = getR2Path(request); const isPathADirectory = isDirectoryPath(path); - ctx.sentry.addBreadcrumb({ + Sentry.addBreadcrumb({ category: 'R2Middleware', data: { r2Path: path, @@ -127,7 +128,8 @@ async function getFile( } } - ctx.sentry.captureException(err); + // todo doesn't this get reported to sentry by the router? + Sentry.captureException(err); throw err; } diff --git a/src/middleware/subtituteMiddleware.ts b/src/middleware/subtituteMiddleware.ts index 6e9cb5f3..0a05431a 100644 --- a/src/middleware/subtituteMiddleware.ts +++ b/src/middleware/subtituteMiddleware.ts @@ -1,3 +1,4 @@ +import * as Sentry from '@sentry/cloudflare'; import type { Context } from '../context'; import type { Router } from '../routes/router'; import type { Request } from '../routes/request'; @@ -25,7 +26,7 @@ export class SubtitutionMiddleware implements Middleware { handle(request: Request, ctx: Context): Promise { const newUrl = request.url.replaceAll(this.searchValue, this.replaceValue); - ctx.sentry?.addBreadcrumb({ + Sentry.addBreadcrumb({ type: 'navigation', category: 'SubstitutionMiddleware', data: { diff --git a/src/routes/router.ts b/src/routes/router.ts index 2db2d115..b2ac4e2d 100644 --- a/src/routes/router.ts +++ b/src/routes/router.ts @@ -1,3 +1,4 @@ +import * as Sentry from '@sentry/cloudflare'; import { IttyRouter, type RequestHandler } from 'itty-router'; import type { Request as WorkerRequest } from './request'; import type { Context } from '../context'; @@ -102,7 +103,7 @@ function middlewareToRoute(middleware: Middleware): WorkerRequestHandler { return response; } catch (err) { // Catch the exception, report to Sentry - ctx.sentry?.captureException(err); + Sentry.captureException(err); // Don't return anything so itty router will continue to next route in // the chain diff --git a/src/utils/provider.ts b/src/utils/provider.ts index 72d8bbc0..2808f679 100644 --- a/src/utils/provider.ts +++ b/src/utils/provider.ts @@ -1,4 +1,4 @@ -import type { Toucan } from 'toucan-js'; +import * as Sentry from '@sentry/cloudflare'; /** * Utility for retrying request sent to a provider's data source @@ -7,8 +7,7 @@ import type { Toucan } from 'toucan-js'; */ export async function retryWrapper( request: () => Promise, - retryLimit: number, - sentry?: Toucan + retryLimit: number ): Promise { let r2Error: unknown = undefined; for (let i = 0; i < retryLimit; i++) { @@ -20,9 +19,8 @@ export async function retryWrapper( } } - if (sentry !== undefined) { - sentry.captureException(r2Error); - } + // again isn't this captured somewhere else? + Sentry.captureException(r2Error); throw r2Error; } diff --git a/src/worker.ts b/src/worker.ts index 67cf7c6f..61239e8b 100644 --- a/src/worker.ts +++ b/src/worker.ts @@ -1,4 +1,4 @@ -import { Toucan } from 'toucan-js'; +import * as Sentry from '@sentry/cloudflare'; import type { Env } from './env'; import responses from './responses'; import type { Context } from './context'; @@ -8,54 +8,45 @@ import { registerRoutes } from './routes'; const router: Router = new Router(); registerRoutes(router); -export default { - async fetch( - request: Request, - env: Env, - ctx: ExecutionContext - ): Promise { - const sentry = new Toucan({ - dsn: env.SENTRY_DSN, - request, - context: ctx, - requestDataOptions: { - allowedHeaders: true, - }, - }); - - sentry.setTag('request_id', crypto.randomUUID()); - - if (env.LOG_ERRORS === true) { - const originalCaptureException = sentry.captureException.bind(sentry); - - sentry.captureException = (exception, hint): string => { - console.error(exception, `(hint=${hint})`); - - return originalCaptureException(exception, hint); +export default Sentry.withSentry( + env => ({ + dsn: env.SENTRY_DSN, + }), + { + async fetch( + request: Request, + env: Env, + ctx: ExecutionContext + ): Promise { + Sentry.setTag('request_id', crypto.randomUUID()); + + // TODO + // if (env.LOG_ERRORS === true) { + // const originalCaptureException = sentry.captureException.bind(sentry); + // sentry.captureException = (exception, hint): string => { + // console.error(exception, `(hint=${hint})`); + // return originalCaptureException(exception, hint); + // }; + // } + + const context: Context = { + env: env, + execution: ctx, }; - } - const context: Context = { - sentry, - env: env, - execution: ctx, - }; - - try { - const response: unknown = await router.fetch(request, context); - - if (!(response instanceof Response)) { - // Didn't get a proper response from the router - throw new TypeError( - `router response not instanceof Response (typeof=${typeof response}, ctor=${response?.constructor?.name})` - ); + try { + const response: unknown = await router.fetch(request, context); + if (!(response instanceof Response)) { + // Didn't get a proper response from the router + throw new TypeError( + `router response not instanceof Response (typeof=${typeof response}, ctor=${response?.constructor?.name})` + ); + } + return response; + } catch (err) { + Sentry.captureException(err); + return responses.internalServerError(err, env); } - - return response; - } catch (err) { - sentry.captureException(err); - - return responses.internalServerError(err, env); - } - }, -}; + }, + } satisfies ExportedHandler +); diff --git a/wrangler.jsonc b/wrangler.jsonc index ac12dda9..90e75b02 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -3,6 +3,7 @@ "name": "dist-worker", "main": "src/worker.ts", "compatibility_date": "2024-09-05", + "compatibility_flags": ["nodejs_compat"], "logpush": true, "preview_urls": false, "vars": {