I need a 2nd pair of eyes if anyone’s around, beca...
# random
s
I need a 2nd pair of eyes if anyone’s around, because #1 it’s late my brainpower is waning; #2, sometimes multiple levels of async stuff confuses me a little 😅 does this code make sense at all?
Copy code
let middyfied = middy(
    Sentry.AWSLambda.wrapHandler<
      ValidatedAPIGatewayProxyEvent<S>,
      APIGatewayProxyResult | undefined
    >(async (event, context) => {
      let claims: JWTClaims | null = null;
      let result: InnerHandlerResult | void;

      await initSentry();
in other words, does it make sense to initialize Sentry (with the DSN, etc) inside the
Sentry.AWS.wrapHandler
? my thinking is that the initialization doesn’t actually matter until Sentry is about to send off an error. all the code in their
wrapHandler
just seems like setup.
welp, I can’t see how this setup can work. 🤔 Sentry init is now async because it makes a call to SSM to fetch the release hash. so then I can’t call that within any of my API funcs because they’re wrapped in
Sentry.AWS.wrapHandler
a
you need top level await support for this probably. you could use a before handler to deal with the init probably but it’ll add to the boot time. 😑
s
Copy code
export function wrapApiHandler<S>(
  schema: S,
  handler: HandlerForPrivateEndpoint<S> | HandlerForPublicEndpoint<S>,
  publicEndpoint = false
): Handler<
  ValidatedAPIGatewayProxyEvent<S>,
  APIGatewayProxyResult | undefined
> {
  let middyfied = middy(async () => {
    await initSentry();

    return new Promise(resolve =>
      Sentry.AWSLambda.wrapHandler<
        ValidatedAPIGatewayProxyEvent<S>,
        APIGatewayProxyResult | undefined
        // @ts-ignore
      >(async (event, context) => {
        let claims: JWTClaims | null = null;
        let result: InnerHandlerResult | void;
this is getting quite ugly 😬 like.. I can’t wrap my head around this level of functional programming
a
while it looks ugly, this should work. Life would’ve been much easier with top-level await though. 😅
s
what does that look like? I thought you can’t use
await
at top level
and no, my code above is totally in a non-working state 😕
I’d rather not have to write
await initSentry()
inside every single API function
a
Node 14 and AWS Lambdas now support it but sst doesn’t. with top level await you could simply return a promise before calling the handler.
s
very curious how Dax has this set up. but I don’t wanna ping him this late
a
you could make the wrapper sync by using the lambda handler callback instead of the async handler, that could work.
f
Yeah I remember @thdxr brought up top level await back then. I think he moved the async stuff inside the Lambda handler as a workaround. I will let him confirm in the morning.
s
oh.. of course! geez. I haven’t used
callback
in so long, I kinda forgot about it.
yeah, cuz Dax said he was fetching his Sentry release from SSM, which is async.. so he’d have to be using some trickery here
a
I remember him mentioning a library called deasync and some trickery related to it.
s
callback
didn’t work 😕 I suppose I’ll wait till tomorrow on this
this is why I’m in the OOP camp vs the FP camp 😄
a
weird lol!
t
I did something terrible to get around the top level await thing. I used deasync package lol
I looked more into supporting it and esbuild doesn't support it yet
s
@thdxr shouldn’t it be possible to wrap the Sentry wrapper (which wraps the Lambda handler) and call
await initSentry()
before returning the Sentry-wrapped handler?
my brain broke last night because I have: my wrapper -> middy -> Sentry wrapper -> handler
that + TypeScript types for function return values + async, I just.. can’t 😅
t
I haven't looked into the middy setup specifically yet. But theoretically yeah it should be possible