1

我认为event.passThroughOnException();应该为我的工作人员设置fail open策略,以便如果我的代码引发异常,原始请求会发送到我的源服务器,但似乎缺少发布数据。我认为这是因为请求正文是可读流,一旦读取就无法再次读取,但是如何管理这种情况呢?

addEventListener('fetch', (event) => {
  event.passThroughOnException();
  event.respondWith(handleRequest(event));
});

async function handleRequest(event: FetchEvent): Promise<Response> {
  const response = await fetch(event.request);

  // do something here that potentially raises an Exception
  // @ts-ignore
  ohnoez(); // deliberate failure

  return response;
}

如下图所示,源服务器没有收到任何正文 ( foobar):

工人游乐场的例子

4

2 回答 2

1

不幸的是,这是一个已知的限制passThroughOnException()。Workers Runtime 使用流式传输请求和响应主体;它不缓冲身体。结果,身体一旦被消耗,就消失了。因此,如果您转发请求,然后再抛出异常,则无法再次发送请求正文。

于 2020-08-19T01:34:48.280 回答
1

通过克隆做了一个解决方法event.request,然后添加一个 try/catch in handleRequest。On ,在传递克隆请求的同时将catch(err)请求发送到源。fetch


// Pass request to whatever it requested
async function passThrough(request: Request): Promise<Response> {
  try {
    let response = await fetch(request)

    // Make the headers mutable by re-constructing the Response.
    response = new Response(response.body, response)
    return response
  } catch (err) {
    return ErrorResponse.NewError(err).respond()
  }
}

// request handler
async function handleRequest(event: FetchEvent): Promise<Response> {
  const request = event.request
  const requestClone = event.request.clone()
  let resp

  try {
    // handle request
    resp = await handler.api(request)

  } catch (err) {
    // Pass through manually on exception (because event.passThroughOnException
    // does not pass request body, so use that as a last resort)
    resp = await passThrough(requestClone)
  }

  return resp
}


addEventListener('fetch', (event) => {
  // Still added passThroughOnException here 
  // in case the `passThrough` function throws exception
  event.passThroughOnException()
  event.respondWith(handleRequest(event))
})

到目前为止似乎工作正常。很想知道是否还有其他解决方案。

于 2020-12-16T19:23:57.423 回答