« get me outta code hell

data, util: principle "translucent errors" & applications - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-11-20 14:31:58 -0400
committer(quasar) nebula <qznebula@protonmail.com>2023-11-20 14:31:58 -0400
commitf87fa920f91d36424e4613ac5da50f46418f4b19 (patch)
tree81d6bfa4d5df7419383ed8fbb8e80e03074b290d
parent87988954ad7314bee59932b0e5ef3474936ed33e (diff)
data, util: principle "translucent errors" & applications
-rw-r--r--src/data/yaml.js9
-rw-r--r--src/util/sugar.js14
2 files changed, 20 insertions, 3 deletions
diff --git a/src/data/yaml.js b/src/data/yaml.js
index 49e05266..dddf5fb2 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -334,6 +334,8 @@ export class FieldCombinationError extends Error {
 }
 
 export class FieldValueAggregateError extends AggregateError {
+  [Symbol.for('hsmusic.aggregate.translucent')] = true;
+
   constructor(thingConstructor, errors) {
     const constructorText =
       colors.green(thingConstructor.name);
@@ -1162,7 +1164,10 @@ export async function loadAndProcessDataDocuments({dataPath}) {
 
   for (const dataStep of dataSteps) {
     await processDataAggregate.nestAsync(
-      {message: `Errors during data step: ${colors.bright(dataStep.title)}`},
+      {
+        message: `Errors during data step: ${colors.bright(dataStep.title)}`,
+        translucent: true,
+      },
       async ({call, callAsync, map, mapAsync, push}) => {
         const {documentMode} = dataStep;
 
@@ -1407,7 +1412,7 @@ export async function loadAndProcessDataDocuments({dataPath}) {
 
         switch (documentMode) {
           case documentModes.headerAndEntries:
-            map(yamlResults, {message: `Errors processing documents in data files`},
+            map(yamlResults, {message: `Errors processing documents in data files`, translucent: true},
               decorateErrorWithFile(({documents}) => {
                 const headerDocument = documents[0];
                 const entryDocuments = documents.slice(1).filter(Boolean);
diff --git a/src/util/sugar.js b/src/util/sugar.js
index ad676914..6c41bca2 100644
--- a/src/util/sugar.js
+++ b/src/util/sugar.js
@@ -325,6 +325,12 @@ export function openAggregate({
   // constructed.
   message = '',
 
+  // Optional flag to indicate that this layer of the aggregate error isn't
+  // generally useful outside of developer debugging purposes - it will be
+  // skipped by default when using showAggregate, showing contained errors
+  // inline with other children of this aggregate's parent.
+  translucent = false,
+
   // Value to return when a provided function throws an error. If this is a
   // function, it will be called with the arguments given to the function.
   // (This is primarily useful when wrapping a function and then providing it
@@ -407,7 +413,13 @@ export function openAggregate({
 
   aggregate.close = () => {
     if (errors.length) {
-      throw Reflect.construct(errorClass, [errors, message]);
+      const error = Reflect.construct(errorClass, [errors, message]);
+
+      if (translucent) {
+        error[Symbol.for(`hsmusic.aggregate.translucent`)] = true;
+      }
+
+      throw error;
     }
   };