Can anyone point me in the right direction for typ...
# general
a
Can anyone point me in the right direction for typescript sourcemaps for lambda functions using sentry (and ideally, gitlab)? (Paging @Sam Hulick as my slack searching suggests you might have some war stories to share!) I have enabled source maps for my functions in SST using
NODE_OPTIONS: '--enable-source-maps'
, and have notified Sentry that there is a release (using the git SHA as the release name). I have also connected Sentry and Gitlab using the official integration. When I force an error from a lambda function, Sentry associates it with the right release, and the release has the full commit history since the previous commit. Source maps are also semi-working, because Sentry tells me the error is in
/backend/services/error.ts
at line
16:9
, instead of
/backend/services/error.js
at line
1928379128:1928391823
or whatever. But despite the typescript path being the exact same path as the source file in my gitlab repository, Sentry isn’t showing any source (beyond the stack trace). I have tried uploading source maps manually to sentry, but the source maps are for
/backend/services/error.js
(note the
js
extension) whereas with source maps enabled, the error reports itself as coming from
/backend/services/error.ts
, so my manually uploaded source maps don’t get picked up. I have also tried turning off
--enable-source-maps
, and just uploading the source maps to sentry, but that also doesn’t work. (Sentry complains that it can’t find the
.js
file in my gitlab repository). Having the correct filename and line numbers is much better than nothing, I was just wondering if anyone’s managed to get the source code to display in Sentry as well.
s
yo I gotcha covered 🙂 with SST, you’ll need an esbuild plugin
step 1: create a file in your SST project,
config/esbuild.js
(attached)
step 2: at the root level of your SST “main” or entry file:
Copy code
app.setDefaultFunctionProps({
  bundle: {
    esbuildConfig: {
      plugins: 'config/esbuild.js'
    }
  }
})
now when you deploy, your source maps will wind up all neat & clean in
.build/sourcemaps
. you can publish those however you wish, but for Sentry, you want to do something like:
Copy code
#!/bin/sh
set -ex

export SENTRY_RELEASE=$(git rev-parse --short HEAD)
yarn sst deploy $*
yarn sentry-cli releases --org myorg --project myproj files $SENTRY_RELEASE upload-sourcemaps .build/sourcemaps
(that’s my deploy script)
a
Thanks @Sam Hulick I will give that a try!
Yay, it’s now working! In addition to @Sam Hulick’s tips above, I also needed to: 1. Disable the Sentry < > Gitlab integration entirely, since Sentry seemed to be ignoring the source maps and trying (but failing) to get the code directly from the repository. The Gitlab integration seems broken currently, since source files just don’t appear, even if the paths are an exact match. 2. Remove
NODE_OPTIONS: '--enable-source-maps'
from my default function properties environment settings, so that errors are thrown using the transpiled and minified filenames (eg error.js not error.ts) 3. Use the Sentry RewriteFrames plugin to strip the
/var/task
path from the stack traces, so that the stack frames match up with the filenames in the source maps. (Note - when uploading source maps to sentry, you can add a
/var/task
prefix to your source maps, but this won’t help, because the source maps themselves don’t make any mention of
/var/task
)
Copy code
Sentry.init({
      dsn: 'https://***.<http://ingest.sentry.io/***|ingest.sentry.io/***>',

      integrations: [
        new RewriteFrames({
          root: '/var/task',
        }),
      ],
I still get a bunch of
../../../
in my source paths when the errors appear in Sentry, which might be fixable by following these instructions, but honestly that is noise I can live with for now 😅
f
Thanks @Sam Hulick @Athol Birtley this is super useful!
s
sure @Frank! @Athol Birtley sorry, forgot the Sentry rewrite part! so many parts to this 🙂 I’d recommend this:
Copy code
const lambdaPathPattern = /^(?:async\s+)?\/var\/task\//;

[...]
new RewriteFrames({
  iteratee: frame => {
    if (lambdaPathPattern.test(frame.filename!)) {
      frame.filename = frame.filename!.replace(
        lambdaPathPattern,
        'app:///'
      );
    }

    return frame;
  },
}),
[...]
it took me hours to figure this out. such a pain
m
i've not had any issue with seeing sourcemaps that are part of the function bundle (as a .map file) - using
NODE_OPTIONS: "--enable-source-maps
a
Interesting, @Mischa Spiegelmock ! What I found when doing that was that Sentry reported the error in the correct location (eg
/backend/services/myendpoint.ts:10
) but that it did not display the source code where the error occurred, because the source map was for a
.js
file, ie
/backend/services/myendpoint.js.map
But my bigger question is how is your source map data making its way to Sentry? Are you uploading them as part of the build process (and if so what are you naming them)? Does Sentry have the ability to “peek inside” a deployed lambda function? Or can the stack trace data be somehow augmented with the source map context (eg the stack frame line plus five lines either side)? My understanding - which could well be mistaken - was that Sentry needed a copy of the source map file in order to display the code where the error occurred.
m
i just look at the stack trace, i was bundling sourcemaps without source
a
Ah right! Yes, if you just want the correct file names and line numbers in the stack trace, then
NODE_OPTIONS: "--enable-source-maps
works well. But if you are lazy and also want the source code from that line (and surrounding lines) shown to you inside Sentry, then I think you need to go through the steps Sam has outlined above.
m
It would be pretty cool if SST could have an option to split out the sourcemaps and upload them to sentry AFTER the deployment (so you can get your code updated faster)
s
@Mischa Spiegelmock this is what I wish most JS frameworks would do: let me specify a source map output directory, and it can dump them all there. then I can decide what to do with it (upload to Sentry or Rollbar, etc). it would be nice if SST some day had an option you could set in sst.json pointing to where the source maps should go. (@Frank) then I could get rid of my esbuild plugin 🙂
t
^ I'm investigating this
I noticed my sourcemap shipped to prod was 3.5mb so now I care about this again 😂
s
@thdxr you talking about uploading the source maps in the Lambda package? it would be cool if we could exclude those from the bundle
I have some maps that are like 5MB 😕
t
I just added the ability to turn them off but you can't do that since you need to copy them over right? That's what I mean I want to support dumping them into a folder
s
hmm.. unsure of the order of how things happen. my esbuild plugin copies the .map files into a separate folder, so it wouldn’t hurt if the .map files weren’t included in the Lambda zip files
t
the option right now disable esbuild from generating them so I think it would break your setup
s
ahh, dang. well, if it were possible to dump the .map files into a folder instead of in the Lambda bundle, that would work. so e.g. if
sourcemapOutputDir
is not defined, it just gets included in the Lambda zip files
m
here's what ya get with Prisma lol... x50 functions
hopefully that will be fixed soon
a
I’ll second this 😄 the ability to generate sourcemaps, but not deploy them in the lambda bundle, would be handy.
m
i'm going to solve it by getting fiber installed thursday lol