Question

Why have Functions and Support NOT IMPROVED 2 years later?

I know I am speaking for many when I write this post. There have been a lot of things said about DigitalOcean Functions at this point, but I would like to get to the bottom of the useless error:

{
  "error": "There was an error processing your request."
}

As it currently stands, you do not have to go far to find questions like this one scattered across the internet: https://www.digitalocean.com/community/questions/app-platform-functions-experience-painful

Literally describing the use of functions as “painful” because of these kinds of error responses. Other questions describe it as a “dead end”. I agree with this sentiment. However, there is also talk elsewhere that describes DO Functions as a service that was added to the offerings that DO already had through an acquisition of another company in 2022 and that the solution is based on Apache OpenWhisk, which is where things like __ow_headers comes from. That knowledge (which I really shouldn’t need to track down or know to make things work) has helped me understand underlying errors in the past and get past the non-descript error above. Adding that to the post for posterity lol.

But regardless of whether you get past the non-descript error initially, there will be a time when you make the SMALLEST inconsequential (in every other environment) change to the code in your repository to continue with your build, where that error comes back, and will not leave, unless you are willing to break down everything you’ve built to find the possible errors and plug and chug (waiting for deployment) for HOURS to verify that you have indeed fixed the “error”, and then clean up the new mess you you’ve now been forced to make, obviously slowing down the development process. This is where I am now.

On this same project about 2 months ago, I also opted for 1 month of the $100/month developer support, just to get me over the hump with DO Functions after reading the horror stories, and having wasted days in previous years, waiting on the support team to respond only for them to say that they couldn’t help me because I didn’t have a support tier that covered developer support. I would not recommend anyone else upgrading support either, because even though the response time was faster, they still did not seem to understand basic development and IT concepts, and I hardly ever got a response from the same person twice in a row. It was like pulling teeth trying to get the support staff to take a look at my code, and I can count on one hand how many times they actually did it. When they did look at the code, I got the simple answer I needed, still days later than expected. Not to mention, if you do upgrade support to the tier with developer support, it will cost $100 if you only use it for a day or less. The description says the payment is prorated, but they do charge you for 1 full month, and then start the proration. While it does technically say that in the details on the site, I will say that most people understand prorated plans as something they are charged for by the day, without “first-month’s rent” being charged regardless. For example, I only had the upgraded service for about 12 days and ended up being charged $140, and had to engage with them over and over to get those simple answers. The first $100 was not charged all at once, as you may think it would be if it is a cost to initiate the service, it was instead charged to me by the day, which felt sneaky. I reached out to get a refund, but they then asked me to show proof that the support staff didn’t do their job…That whole support saga ended up being a waste of time and money, except I am somewhat further along with using serverless.

Now, let’s talk about this error:

For me, I have a main function that starts like this:

import json
from context.context import secured_user, path_to_list, is_valid_uuid
from crud.r import list_objects
from resources.resources import valid_objects


def main(event):
    method = event['http']['method']
    print(method)

    path_list = path_to_list(event['http']['path'])
    print('path list: ', path_list)

    is_valid_request = False

    obj = None
    object_user_type = None
    public_id = None

    obj = path_list[0]
    if obj in valid_objects:
        object_user_type = path_list[1]
        if object_user_type in ['system', 'admin', 'customer']:
            is_valid_request = True

            if len(path_list) == 3:
                public_id = path_list[2]



    print("Valid Request: ", is_valid_request)
    if not is_valid_request:
        return {
            "statusCode": 400,
            "headers": {
                'Access-Control-Allow-Credentials': 'true'
            },
            "body": {'error': "Invalid Request"}
        }
    else:
        if method == "OPTIONS":
            print("options request")
            return {
                "statusCode": 200,
                "headers": {
                    'Access-Control-Allow-Credentials': 'true',
                }
            }

        if method == "GET":
            user_type, user = secured_user(event)
            if not isinstance(user, dict):
                filters = None
                if 'filters' in event.keys() and isinstance(event['filters'], dict):
                    filters = event['filters']
                    print("filters found")
                if public_id is None:
                    print("made it to list_objects")
                    endpoint = list_objects(user, user_type, obj, object_user_type, filters=filters)
                    return {
                        "body": endpoint,
                        "statusCode": endpoint['statusCode'],
                        "headers": {
                            'Access-Control-Allow-Credentials': 'true',
                        }
                    }
                else:

                    endpoint = {'statusCode': 400, 'error': "not available yet"}

                    return {
                        "body": endpoint,
                        "statusCode": endpoint['statusCode'],
                        "headers": {
                            'Access-Control-Allow-Credentials': 'true',
                        }
                    }

And in context/context.py I have this function:

def path_to_list(path):
    """
    Convert a path string into a list of segments, removing the leading slash.

    Parameters:
    path (str): The path string to be converted.

    Returns:
    list: A list of segments from the path.
    """
    # Remove the leading slash if it exists
    if path.startswith('/'):
        path = path[1:]

    # Split the path by slashes and return the resulting list
    path_list = path.split('/')
    return [entry for entry in path_list if entry]

This function set is correctly connected to BetterStack in the DO App Platform Dashboard and has given me the error logs just fine in the past, in fact there are other deployed endpoints in the same function set that works as expected, and they all start the same way.

On principle, I do not understand how it is possible to supply a main function such as this, that only takes event as a parameter and not have it print something as simple as the method or the path_list. None of the files I am importing have errors in them. All I am getting back is the. non-descript error message and no logs in BetterStack. I do not wish to expand my cloud footprint, would much rather stay with DigitalOcean and their other products work just fine, but I do need serverless functions for scalable architecture, and I might have to go elsewhere if I can’t get this figured out.


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Dikshith Shetty
DigitalOcean Employee
DigitalOcean Employee badge
September 12, 2024

Hello @thefrisson

Thank you for your honest feedback. We’ve created both a support ticket and an engineering ticket based on the information you provided. You should have received an email with the support ticket details. If you have any additional information to share about this issue, please follow up on that ticket.

Thank you! Dikshith

Did you ever find your answer?

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.