lib/modules: Throw earlier when module function does not return attrs

`m` must always be an attrset at this point. It is basically always
evaluated. This will make it throw when any of the attrs is accessed,
rather than just `config`. We assume that this will improve the error
message in more scenarios.

Changed files
+23 -3
lib
+2 -3
lib/modules.nix
···
config = addFreeformType (addMeta (m.config or {}));
}
else
+
lib.throwIfNot (isAttrs m) "module ${file} (${key}) does not look like a module."
{ _file = toString m._file or file;
key = toString m.key or key;
disabledModules = m.disabledModules or [];
imports = m.require or [] ++ m.imports or [];
options = {};
-
config =
-
lib.throwIfNot (isAttrs m) "module ${file} (${key}) does not look like a module."
-
addFreeformType (addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports" "freeformType"]));
+
config = addFreeformType (addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports" "freeformType"]));
};
applyModuleArgsIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
+1
lib/tests/modules.sh
···
checkConfigOutput '"beta"' config.nodes.foo.settingsDict.c ./deferred-module.nix
# errors from the default module are reported with accurate location
checkConfigError 'In `the-file-that-contains-the-bad-config.nix, via option default'\'': "bogus"' config.nodes.foo.bottom ./deferred-module.nix
+
checkConfigError '.*lib/tests/modules/deferred-module-error.nix, via option deferred [(]:anon-1:anon-1:anon-1[)] does not look like a module.' config.result ./deferred-module-error.nix
# Check the file location information is propagated into submodules
checkConfigOutput the-file.nix config.submodule.internalFiles.0 ./submoduleFiles.nix
+20
lib/tests/modules/deferred-module-error.nix
···
+
{ config, lib, ... }:
+
let
+
inherit (lib) types mkOption setDefaultModuleLocation evalModules;
+
inherit (types) deferredModule lazyAttrsOf submodule str raw enum;
+
in
+
{
+
options = {
+
deferred = mkOption {
+
type = deferredModule;
+
};
+
result = mkOption {
+
default = (evalModules { modules = [ config.deferred ]; }).config.result;
+
};
+
};
+
config = {
+
deferred = { ... }:
+
# this should be an attrset, so this fails
+
true;
+
};
+
}