node-convict icon indicating copy to clipboard operation
node-convict copied to clipboard

Providing a default of `undefined` prevents format from being checked

Open molomby opened this issue 5 years ago • 3 comments

The docs are clear that defaults must be supplied and, although the specifics could be improved (#254), not supplying a default value usually errors out.

However, if undefined is given for a default value and the environment variable is also undefined, the format function is never called. This results in bugs like this...

var convict = require("convict");

var config = convict({
  something: {
    format: (val) => {
        if (typeof val === 'undefined' || val === null || val === '') {
            throw new Error('must be a non-empty string');
        }
    },
    default: undefined,
    env: "SOMETHING",
  },
});

config.validate({ allowed: 'strict' });

// If the `SOMETHING` env var isn't set, this will return `undefined` rather than erroring
// The format() function is never called
config.get('something');

Tested on 4.4.1, see RunKit

molomby avatar Feb 05 '19 04:02 molomby

If you hit this in your own usage, one workaround is to set a default of null instead of undefined.

molomby avatar Feb 05 '19 04:02 molomby

This is actually really useful for trying to implement optional config properties so... thanks!

cappslock avatar Jul 18 '19 19:07 cappslock

validate don't check property with default === undefined and value === undefined... Set another value for default. ;-)

https://github.com/mozilla/node-convict/commit/553537910c1708d738a36a3a53c570adf7efe1ba#diff-7763d1369911b91b757ba7ff51d734a2R65

Solution
var convict = require("convict");

var config = convict({
  something: {
    format: function (val, schema) {
        console.log(arguments);
        if (schema.env && val === '') {
          throw new Error(`env[${schema.env}] is not set !`)
        }
        if (typeof val === 'undefined' || val === null || val === '') {
            throw new Error('must be a non-empty string');
        }
    },
    default: '',
    env: "SOMETHING",
  },
});

config.validate({ allowed: 'strict' });

// If the `SOMETHING` env var isn't set, this will return `undefined` rather than erroring
// The format() function is never called
console.log(config.get('something'));

image

A-312 avatar Jan 06 '20 22:01 A-312