Receiving 404 "Access Denied" error on edge, but responds with 200 on serverless

I recently made a new deployment to my project and hitting one of the routes, I get back a 404 with the following message:
https://moovweb-docs-xdn-examples-api-default.moovweb-edge.io/category/hats

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>C13FB417A0589616</RequestId>
<HostId>muZLdeOznycLCmLy7Y9051woCMmzQhtGOirD5Or7PO5zO948OoAseVBogT7IWJPAy3YQAS555Y8=</HostId>
</Error>

However, when I skip the edge and hit the serverless URL, it loads fine: https://moovweb-docs-xdn-examples-api-main-13.free.moovweb.io/category/hats

That error looks like it’s coming from S3. I assume the URL should point to something referenced by serveStatic in your router?

This particular path isn’t being handled via serveStatic. I do have a hierarchy of static JSON files that I would like to read in and map the contents of those files into a single response.

Let’s say I have the following hierarchy for static assets: /assets/category/hats/1.json, ...2.json, etc

In my handler, I am using require to load in that directory context using require.context('../../assets/category/hats/', true)

This way I can then loop over modules (json files) within that webpack context, read them in, manipulate the data and serve that as my response.

The webpack approach may not be the ideal solution, but I did not see any other available handlers that would enable me to read in static files.

In this case, the problem turned out to be attempting to send a response based on the request, without wrapping the logic in compute. For for example:

router.get('/foo', ({ send, request }) => {
  if (request.url) {
    send('something')
  } else {
    send('something else')
  }
})

The problem with the above code is that the handler is run at build time, so that the edge logic can be compiled. If you need compute a response based on the request, that code needs to run in the serverless cloud, at runtime. You do this by wrapping it in compute:

router.get('/foo', ({ send, compute }) => {
  compute(request => {
    if (request.url) {
      send('something')
    } else {
      send('something else')
    }
  })
})

The compute function ensures that the code contained within executes at runtime, in serverless, not at build time.

Can this same concept be applied with static assets using serveStatic? I’d like to use compute to determine the path of an asset and serve it. Similar error, but instead of a 404 I am getting a 403. I suspect the asset is in a different context in serverless and thus why I am seeing a 403.

compute((req) => {
  if (req.params && req.params.id) {
    const id = String(req.params.id)
    const category = id.split('-')[0]

    serveStatic(`assets/category/${category}/${id}.json`)
  } else {
    send('', 404, 'Not Found')
  }
})

@tristan.lee It can be, but keep in mind that you’ll be running compute for every cache miss, so make sure you’re caching the response at edge.