How can I set up AwsWafIntegration.fetch to return a failed response instead of throwing an error?

200 views Asked by At

AWS Web Waf integration throws an error "TypeError: Failed to fetch", instead of returning a failed response when using AwsWafIntegration.fetch with a POST requests that requires a CAPTCHA. It works for requests that don't require CAPTCHAs, or when the CAPTCHA has successfully been completed, and for a moment it also returned failed responses but I can't reproduce the conditions that made it work.

For context, I'm using a load balancer attached to my Web Acl and I've configured the rules to allow all the HTTP OPTIONS method requests, which is required to make the pre-fetch condition work when using the CAPTCHA integration.

const result = await AwsWafIntegration.fetch(url, {
        method: "POST",
        body: send_dat,
});

if (result.status === 405) {
    const container = document.querySelector("#my-captcha-box");
    AwsWafCaptcha.renderCaptcha(container, {
        apiKey: "...API key goes here...",
        onSuccess() {
            // Try loading again, now that there is a valid CAPTCHA token
            loadData();
        },
    });
    return;
}

I was hoping to use the workflow above outlined in the official docs. But since AwsWafIntegration.fetch throws an error, I can't tell if it's a blocked response, another error, or if it's a request that requires a captcha. Now, I wrap it in a try-catch logic and have to open the captcha for all "TypeError: Failed to fetch", but this has led to a terrible user experience.

Try-Catch Logic

async function wafRequest(url, send_data) {
  let wafRes;
  try {
    wafRes = await AwsWafIntegration.fetch(url, {
      method: "POST",
      body: send_data,
    });
  } catch (error) {
    console.log("An error occurred: ", error);
  }

  if (wafRes && wafRes.ok) {
    return await handleResponse(wafRes, url);
  }


  if (!wafRes || (wafRes && wafRes.status === 405)) {
    await displayCaptchaAndFetchToken();

    let newWafRes;
    try {
      newWafRes = await AwsWafIntegration.fetch(url, {
        method: "POST",
        body: send_data,
      });
    } catch (error) {
      console.log("An error occurred: ", error);
    }

    if (newWafRes && newWafRes.ok) {
      return await handleResponse(newWafRes, url);
    } else {
      throw new Error("WAF check failed after captcha");
    }
  }
}
0

There are 0 answers