serverless: Undefined variables being casted to the "undefined" string
This is a Bug Report
Description
- What went wrong?
In the serverless.yml file I have defined some environment variables:
provider:
name: aws
runtime: nodejs6.10
profile: jagi
environment:
STAGE: ${opt:stage}
In some cases ${opt:stage} may be undefined, for example on localhost when using serverless-offline. When it’s undefined it gets converted to the "undefined" string.
- What did you expect should have happened?
I would expect it to be just undefined. It’s kinda weird to make comparisons like:
if (process.env.STAGE === 'undefined')
instead
if (process.env.STAGE === undefined)
Additional Data
- Serverless Framework Version you’re using: 1.10.2
- Operating System: MacOS 10.12.4
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 3
- Comments: 16 (15 by maintainers)
Sounds great.
Just to recap, if you explicitly set a value to
nullin yourserverless.ymlthen the framework won’t throw an error at build time. However, if you simply omit a value, causing the${}variable to resolve toundefined, then the framework will throw an error - as opposed to just the warning that it currently logs today.I think that gives strong feedback to users that something is wrong, but it also does allow enough flexibility to handle any edge cases where for some reason you do want to have a default null env var.
That seems reasonable. So, just throw an error at build time if an env var wasn’t set?
One concern that comes to mind though is that would make it impossible to deliberately omit an environment variable, no? And sometimes people do want to pass in an empty or null value to an environment variable, say if there’s a default that can optionally be overridden (e.g. use the hardcoded default in staging and override through an env var in prod, or, looking at it again, @jagi’s case on this issue, where
${opt:staging}isn’t set when running locally withserverless-offline).Or, maybe I’m misunderstanding option 3?
Hi @pmuens thanks for the warm welcome!
As for your concern about language independence, I was thinking about two different ways to approach this:
Just don’t add the key/value pair to the environment object/hash/dictionary if the input from
serverless.yamlis undefined. So, from @jagi’s example, if${opt:stage}evaluated toundefinedthen you simply wouldn’t put a"STAGE"key in the environment object. Doing so would mean thatprocess.env.STAGE === undefinedwould be true. In Python:os.environ.get("STAGE") is None. And in Java:System.getenv().get("STAGE") == null. This makes it really clear that the env var was never set, but it’s less immediately clear where the problem is. New Serverless developers might not be sure whether they messed something up in the yaml file or if the problem was upstream in their local environment.Go ahead and set the key but make the value an empty string. Checking if an env var is ‘null or empty’ is pretty common across languages too. And I can see how that might be more expected as a developer using Serverless - you know at least something is working, since the key is getting from
serverless.yamlinto the env, but there clearly is a problem with the key, so you’d look at what was being templated into the yaml file. That said, people would have to check null-or-empty if they wanted to be safe before using an env var.Overall I’m slightly more in favor of 1) just because it seems more straightforward. It’s a pretty natural thing to think that maybe empty / null /
undefinedvalues aren’t added to the environment. And it requires less work of developers who want to add checks around env vars - just check if it’sundefined/None/null.