Timon
Timon

Reputation: 95

Random Connection Error in Google Cloud Functions (Python)

Because I have been getting some unexpected CORS errors in my browser console for the past few weeks, I have set up a super simple Python script with a single function inside Google Cloud Functions:

def prepData(request):

    if request.method == 'OPTIONS':
        headers = {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'POST',
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Max-Age': '3600'
        }
        return ('', 204, headers)

    headers = {
        'Access-Control-Allow-Origin': '*'
    }
    return ("", 200, headers)

It looks very similar to the function presented by Google on their documentation page with one major difference: I am using POST rather than GET.

When calling the function, I am seeing a success message (Function execution took 13 ms, finished with status code: 200) in around 50% of cases and a connection error (Function execution took 11 ms, finished with status: 'connection error') in all other cases. Whenever I am getting a connection error inside GCF, Chrome's console logs an error: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I am currently considering three possible causes:

  1. GCP Infrastructure. I have found some related questions where Google was acknowledging some infrastructure issues.
  2. Python error
  3. CORS error (user sideshowbarker says: very unlikely)

What is the cause of the issue and how do I fix it?


Here is the JS code that calls the Python script:

    const xhr = new XMLHttpRequest();
    xhr.open("POST", "[URL]");
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(stringified_serialized_data);

Edit on 4/2/20:

I have discovered a way to not trigger the error: Add some code between the two return statements. I have not yet figured out what kind of code is needed, but d = request.get_json() appears to be sufficient. The new code looks as follows:

def prepData(request):

    if request.method == 'OPTIONS':
        headers = {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'POST',
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Max-Age': '3600'
        }
        return ('', 204, headers)

    d = request.get_json() #THIS LINE IS NEW

    headers = {
        'Access-Control-Allow-Origin': '*'
    }
    return ("", 200, headers)

Upvotes: 2

Views: 1797

Answers (2)

Mayank Gupta
Mayank Gupta

Reputation: 31

I fixed this issue by increasing the RAM allocated to the Cloud Function. Mine had 512MB when this issue was occurring. I increased it to 1GB and it started working like a charm.

Upvotes: 0

Martín De la Fuente
Martín De la Fuente

Reputation: 6726

UPDATE

After digging further, we realized that the problem is actually a bug in the Google Cloud Function service. This bug affects specifically cloud functions using the Python runtime. Those functions will raise a connection error (and will return code 500) if they get an HTTP POST request with a body larger than ~10 KB. Interestingly though, this won't happen in every request with such characteristics, but in most of them.

The Google support service was informed about this issue and they acknowledged the bug. They created a public issue in their issue tracker that should be updated with additional information according to the progress of the solution. By the day of this writing the issue is marked as "New".

Workaround: as suggested by @Timon, it seems that calling request.get_json() in the function seems to fix the issue for requests with JSON bodies. This won't work if the body of your request uses a different format.


OLD ANSWER

I just set up a clean GC Function with the exact same code you provided and it worked flawlessly. I can make requests through the browser (using your JS code) and they never fail.

This leave us with two options:

  1. There is something in your browser or your internet connection that is causing some of your requests to fail.
  2. There is something in your GCF that is causing errors.

For option 1 check this:

  • Do the failed requests occur in batches? Or they are randomly sampled? If they occur in batches the problem could be your internet connection.
  • Are you using some sort of VPN or proxy? Try disabling it.
  • Have you tried multiple browsers? If not, try. Is the described behaviour the same in all of them?

For option 2, check this:

  • Is your function the exact same code you published? If not, and it has more code, the problem is probably there.
  • Do you deploy your function using some command line tool? Is yes, try to do it through the inline editor in GCP website.
  • In the networking setting of your function (in advanced settings), be sure to select "Allow all traffic"

Upvotes: 7

Related Questions