toucan-js
toucan-js copied to clipboard
Source maps still don't seem to be working
Followed the guide in the README and the thread but I'm still getting errors when attempting to link to my source map.
Maybe I'm missing or misunderstanding something still?
addEventListener('fetch', (event) => {
const sentry = new Toucan({
dsn: SENTRY_DSN,
event,
environment: 'development',
release: 'pre-release',
allowedCookies: /(.*)/,
allowedHeaders: /(.*)/,
allowedSearchParams: /(.*)/,
rewriteFrames: {
root: '/'
}
})
event.respondWith(handleRequest(event, sentry))
})
const SentryWebpackPlugin = require('@sentry/webpack-plugin')
module.exports = {
entry: './src/index.js',
target: 'webworker',
devtool: 'cheap-module-source-map',
node: {
fs: 'empty'
},
plugins: [
new SentryWebpackPlugin({
authToken: 'abc123',
release: 'pre-release',
org: 'abc',
project: '123',
include: './dist',
urlPrefix: '/',
}),
],
}
Your config seems OK to me. Have you tried devtool: source-map?
I have yes, I can't use that directly though as the output is too large to upload.
✨ Built successfully, built project size is 1 MiB. ⚠️ Your built project has grown past the 1MiB size limit and may fail to deploy. ⚠️
Currently I'm getting around this with two different webpack files, one to build and upload the src map and one to just upload the worker code. Works fine.
// wrangler.toml
name = "name"
type = "webpack"
account_id = "account-id-abc123"
workers_dev = true
webpack_config = "webpack.config.js"
[env.srcmap]
webpack_config = "webpack.config.srcmap.js"
// webpack.config.js
const webpack = require('webpack')
module.exports = {
entry: './src/index.js',
target: 'webworker',
node: {
fs: 'empty'
},
module: {
rules: [
{
test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'
}
]
},
plugins: [
new webpack.ExtendedAPIPlugin(),
]
}
// webpack.config.srcmap.js
const SentryPlugin = require('webpack-sentry-plugin')
const webpack = require('webpack')
module.exports = {
entry: './src/index.js',
target: 'webworker',
devtool: 'source-map',
node: {
fs: 'empty'
},
module: {
rules: [
{
test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'
}
]
},
plugins: [
new webpack.ExtendedAPIPlugin(),
new SentryPlugin({
apiKey: 'sentry-api-key-abc123',
organization: 'org-abc123',
project: 'project-abc123',
deleteAfterCompile: true,
release: (hash) => hash
})
],
}
// package.json
{
"private": true,
"main": "./src/index.js",
"scripts": {
"start": "wrangler dev",
"deploy": "wrangler build -e srcmap ; wrangler publish"
},
"dependencies": {
...
},
"devDependencies": {
...
}
}
// index.js
...
const sentry = new Toucan({
pkg,
event,
dsn: SENTRY_DSN,
environment: isDev ? 'development' : 'production',
release: __webpack_hash__,
attachStacktrace: true,
allowedCookies: /(.*)/,
allowedHeaders: /(.*)/,
allowedSearchParams: /(.*)/,
rewriteFrames: {
root: '/'
}
})
...
% npm run deploy
> deploy
> wrangler build -e srcmap ; wrangler publish
✨ Built successfully, built project size is 1 MiB. ⚠️ Your built project has grown past the 1MiB size limit and may fail to deploy. ⚠️
✨ Built successfully, built project size is 315 KiB.
✨ Successfully published your script to
https://project-name.workers.dev
i've been wrestling with source-maps today too, and I found that I could not get source maps to work with CF Workers + SentryWebpackPlugin + Toucan unless I removed the //# sourceMappingURL= link from the end of the js bundle by setting devtool: hidden-source-map in the webpack config.
We're using webpack 5, and wrangler 1.19 and have configured wrangler to treat the project as type = "javascript".
We configure the SentryWebpackPlugin like this:
new SentryWebpackPlugin({
release: gitRevisionPlugin.version(),
include: './dist',
urlPrefix: '/',
org: '***',
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_TOKEN
})
and Toucan like this:
new Toucan({
dsn: SENTRY_DSN,
context: event,
allowedHeaders: ['user-agent'],
allowedSearchParams: /(.*)/,
debug: false,
rewriteFrames: {
root: '/'
},
environment: ENV,
release: VERSION,
pkg
})
which means we generate the bundle js and the source map in the dist dir, and both files get uploaded to sentry and then cloudflare on publish. The source maps show up on the release in Sentry but they just would not work until I switched the webpack devtool from devtool: source-map devtool: hidden-source-map, which only removes //# sourceMappingURL= link from the bundle.
Is that expected? I'd love to understand what is going on there. From the README for toucan it seem like that is not normal.
@olizilla Do you have .map file along with your compiled .js file in your dist folder when you use devtool: source-map? If yes, and assuming your worker script is named worker.js, is your worker.js referencing the correct map file? It should look like this: sourceMappingURL=worker.js.map. Also check if both worker.js and worker.js.map show in Sentry under your project's source maps (or release artifacts if you use older version of Sentry):

Seems also not working with modules.
Aye, we just switched to esm modules on cloudflare, and our source maps are no longer showing up on Sentry.
I got it working with esm by using the rewriteFrames.iteratee property to strip a leading . character from the Stackframe.filename that we were seeing on errors sent from cloudflare to sentry.
rewriteFrames: {
// strip . from start of the filename ./worker.mjs as set by cloudflare, to make absolute path `/worker.mjs`
iteratee: (frame) => ({ ...frame, filename: frame.filename.substring(1) })
},
happy sourcemap'd sentry error from an es module flavour worker
Before this change the raw JSON view of an error on Sentry showed that the filename property would be set to ./worker.js
unhappy sentry errror
"exception": {
"values": [
{
"type": "Error",
"value": "A deliberate error!",
"stacktrace": {
"frames": [
{
"function": "async Object.fetch",
"filename": "./worker.mjs",
"abs_path": "./worker.mjs",
If I configure Toucan with rewriteFrames.root: '/' to prepend / to the filename, then Sentry shows, the filename and abs_path as "/./worker.mjs" and the only way to get Sentry to locate the uploaded bundle was to also set the urlPrefix option one uploading the files to Sentry to the same like urlPrefix: ~/./ which seemed kinda gross, but worked... I opted for just stripping the . from ./worker.mjs in the Toucan config as it seemed neater, as it also meant I could avoid specifying the urlPrefix when uploading them as the default is ~/ which works as, i learnt recently:
as
~/is wildcard matcher for anyprotocol+hostpair. – https://github.com/getsentry/sentry-cli/issues/894#issuecomment-944347277
I got it working with esm by using the rewriteFrames.iteratee property to strip a leading . character from the Stackframe.filename that we were seeing on errors sent from cloudflare to sentry.
Thanks so much - this fixed the issue for me, too 🙏
I'm building with esbuild (so no webpack plugin as mentioned in docs), so it was additionally necessary for me to set
--urlPrefix '/'
This broke again when we upgraded to wrangler v2... still investigating.
OK! It seems that Cloudflare does it's own bundling of your worker code.
For your source map to work you need to disable that new feature in your wrangler.toml by setting no_bundle = true.
🎩 Hat tip to @hugomrdias for the discovery in https://github.com/nftstorage/nft.storage/pull/2094
We also had to revert the rewriteFrames config listed in https://github.com/robertcepa/toucan-js/issues/54#issuecomment-1054169127 back to the simpler root: / form, and update our bundle name to be worker.js
rewriteFrames: {
root: '/'
},
see: https://github.com/web3-storage/web3.storage/pull/1838
This should be a solved problem in 3.0.0. Mind giving it a shot? I added starters for various bundlers in https://github.com/robertcepa/toucan-js/tree/master/examples
In 3.0.0 you shouldn't need to use rewriteFrames or configure root in source map plugin, things should just work™
This should be a solved problem in 3.0.0. Mind giving it a shot?
@robertcepa I updated our project to use [email protected] and emulated the wrangler-basic example (omitting wrangler.toml no_bundle i.e. no_bundle=false).
It seems to be working!
Thanks for all your advice. 🙏