Create-React-App-Lambda dadjoke fails with 503 out of the box

Hi all, well, the title says it all. I am a total newbie here so I am wondering what I am missing. I follow the instructions on create-react-app-lambda and when I click the async dad joke button, I get Request failed with status code 503, which is a really bad dad joke if you ask me :grinning:.

My site is live here. To get this error, I do the following:

For what it’s worth, the other button with a hello world callback works, so it appears to me that the general function setup is working, and there might “just” be a problem with this api call itself. I figured I would ask the experts here before going and debugging – maybe I am missing something simple here, as I have basically never used Netlify before today.

I’ve tried this a few times over the course of the last hour or so, so it doesn’t seem to be a particularly transient error. I also re-started the tutorial from scratch and did nothing else but push that button, and it still fails.

Thanks for the support!

The 503 is not coming from Netlify, but the API endpoint giving the jokes. This is the code responsible:

As you can see, it sends a status code of 500 and not 503.

Also, your function console will show the error: Netlify App

It says:

isAxiosError: true

which means, Axios failed to fetch the data, in this case, due to 503 from the upstream server.

Hi,
Thanks for the response! This was very helpful for me to find the underlying issue. There is indeed a problem with the response from the Joke API on the deployed site. The only way I could make this tutorial run on Netlify was to switch out the API for another one. This commit on my fork of the tutorial solves the issue, as seen on my live site here. I would be happy to prepare a pull request for this, updating the function names and documentation as well as simply making it work, as I have in my own private commit above.

There seems to be a compatibility issue between deployed tutorial function and the API it is calling. As far as I can tell, the Joke API endpoint itself works as expected in manual testing; see the results with cURL below. I don’t understand enough about the setup to understand what is going on, but I have a suspicion that Netlify is being blocked by the joke API site. For example, it could be that Cloudflare’s Super Bot Fight Mode is turned on for that site, blocking all requests from AWS Lambda – but that is only my suspicion with little knowledge of the internals of either system.

The following is the result of my testing, done locally with cURL to try to get to the bottom of this, since I do understand what is going on there :grinning:. To debug this, I am copying the axios GET request as a cURL request from the Chrome Dev Tools, and running it locally.

Using the default request from the tutorial reproduces the 503 at the command line:

$ curl 'https://imaginative-seahorse-cb2baf.netlify.app/.netlify/functions/async-dadjoke' \
  -H 'authority: imaginative-seahorse-cb2baf.netlify.app' \
  -H 'accept: */*' \
  -H 'accept-language: en-US,en;q=0.9' \
  -H 'referer: https://imaginative-seahorse-cb2baf.netlify.app/' \
  -H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"' \
  -H 'sec-ch-ua-mobile: ?1' \
  -H 'sec-ch-ua-platform: "Android"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: same-origin' \
  -H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36' \
  --compressed
{"msg":"Request failed with status code 503"}

Note that the above GET request is made to the Netlify function’s URL. If you try to reproduce this now with my site’s URL, it will give a random name from the replaced API. Starting the tutorial from scratch and using that URL should, however, reproduce this result at the command line (and in the browser).

If on the other hand I replace only the URL with the original dad joke API endpoint, bypassing the Netlify function, but otherwise using the identical request, I get the full HTML response from the API:

$ curl 'https://icanhazdadjoke.com' \
  -H 'authority: imaginative-seahorse-cb2baf.netlify.app' \
  -H 'accept: */*' \
  -H 'accept-language: en-US,en;q=0.9' \
  -H 'referer: https://imaginative-seahorse-cb2baf.netlify.app/' \
  -H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"' \
  -H 'sec-ch-ua-mobile: ?1' \
  -H 'sec-ch-ua-platform: "Android"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: same-origin' \
  -H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36' \
  --compressed
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
…

Replacing accept: */* with 'accept: application/json yields the expected result of a dad joke in JSON format, giving a response at the command line similar to what is expected in the website’s function call.


$ curl 'https://icanhazdadjoke.com' \
  -H 'authority: imaginative-seahorse-cb2baf.netlify.app' \
  -H 'accept: application/json' \
  -H 'accept-language: en-US,en;q=0.9' \
  -H 'referer: https://imaginative-seahorse-cb2baf.netlify.app/' \
  -H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"' \
  -H 'sec-ch-ua-mobile: ?1' \
  -H 'sec-ch-ua-platform: "Android"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: same-origin' \
  -H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36' \
{"id":"uPu4MRZLmrc","joke":"Want to hear a chimney joke? Got stacks of em! First one's on the house","status":200}

Now that I have swapped out the API https://icanhazdadjoke.com' for https://random-data-api.com/api/users/random_user and data.joke for data.first_name the site itself works, as of course does the local command line call. Note that the function name and URL is unchanged (as of yet) and is still called async-dadjoke, whereas the response comes from the random fake data generator and not from the dad joke API:

$ curl 'https://imaginative-seahorse-cb2baf.netlify.app/.netlify/functions/async-dadjoke' \
  -H 'authority: imaginative-seahorse-cb2baf.netlify.app' \
  -H 'accept: */*' \
  -H 'accept-language: en-US,en;q=0.9' \
  -H 'referer: https://imaginative-seahorse-cb2baf.netlify.app/' \
  -H 'sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"' \
  -H 'sec-ch-ua-mobile: ?1' \
  -H 'sec-ch-ua-platform: "Android"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: same-origin' \
  -H 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36' \
  --compressed
{"msg":"Hans"}

My conclusion in all of this is that the issue I encountered is not an error of my causing and also likely not transient, but likely due to a network configuration change on the side of the API in the tutorial. I find the tutorial itself very helpful and quick and a great way to quickly deploy. I will be using my own fork of this with an updated API call, and I would be happy to contribute by making an PR to the upstream repository.