Errors as data
yen never calls throw. When something is wrong, the read gives null, evaluation continues,
and the errors query lists a record. An empty list means the fleet is valid.
Error records
Section titled “Error records”Each record has error and from for people, and code, path, got, want, fix, class and near
for tools and agents. class is fixable when an edit to the data fixes it, and authority when no edit
by this author can.
{ yen, ... }:{ yen.host.cache = { addr = "10.0.0.5"; bakup = false; };}[ { class = "fixable"; code = "unknown-field"; error = "unknown field bakup"; fix = "declare yen.kinds.host.fields.bakup, or use a declared field"; from = "host:cache"; near = [ "backup" ]; path = [ "bakup" ]; } { class = "fixable"; code = "duplicate-addr"; error = "10.0.0.1 is the address of db and web"; fix = "give each host its own addr"; from = "fleet:main"; got = "10.0.0.1"; path = [ "addr" ]; }]Your own checks
Section titled “Your own checks”An aspect key errors gives records, or plain messages. yen sets from to the scope that gave it: an aspect cannot
report for another scope. A record without class is fixable.
This fleet has two hosts with one address:
{ yen, lib, ... }:{ yen.kinds.fleet = { spawns.host = _: yen.host; sinks.out.reduce = yen.lib.reduce.merge; sinks.warnings.out = { warnings, ... }: { inherit warnings; }; # messages that do not fail the fleet }; yen.kinds.host.fields = { addr = lib.types.str; backup = yen.lib.opt lib.types.bool true; };
yen.fleet.main = { }; yen.host.web.addr = "10.0.0.1"; yen.host.db.addr = "10.0.0.1"; yen.host.scratch = { addr = "10.0.0.9"; backup = false; }; yen.flake = { out, ... }: out;}# An aspect key `errors` gives error records, or plain messages. Nothing throws. `from` is always the giving scope.{ yen, lib, ... }:let byAddr = lib.groupBy (h: h.addr) (lib.attrValues yen.host);in{ yen.aspects.unique-addr = { at = yen.kinds.fleet; errors = lib.concatLists ( lib.mapAttrsToList ( a: hs: lib.optional (lib.length hs > 1) { code = "duplicate-addr"; error = "${a} is the address of ${lib.concatMapStringsSep " and " (h: h.name) hs}"; fix = "give each host its own addr"; path = [ "addr" ]; got = a; } ) byAddr ); }; yen.aspects.no-backup = { at = yen.lib.all [ yen.kinds.host (s: !s.backup) ]; warnings = { host, ... }: "${host.name} has no backup"; };}[ { class = "fixable"; code = "duplicate-addr"; error = "10.0.0.1 is the address of db and web"; fix = "give each host its own addr"; from = "fleet:main"; got = "10.0.0.1"; path = [ "addr" ]; }]Warnings
Section titled “Warnings”A warning is a message that does not fail the fleet. It is a plain sink with list reduce, here given
to the flake as warnings:
[ "scratch has no backup"]