« get me outta code hell

replacer: error postprocessing media tags w/o src - 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>2025-06-15 14:02:21 -0300
committer(quasar) nebula <qznebula@protonmail.com>2025-06-15 14:02:21 -0300
commit188a301e45685be5b233a55b158a9ec100d4052a (patch)
tree75fa7d71fee3f3c87968deaf4e7470c4b2875e30
parent99d7e591bb49ef5a6fd82c7e65886bc33e13ef72 (diff)
replacer: error postprocessing media tags w/o src
-rw-r--r--src/replacer.js38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/replacer.js b/src/replacer.js
index 0698eced..927ea9ef 100644
--- a/src/replacer.js
+++ b/src/replacer.js
@@ -8,7 +8,7 @@
 import * as marked from 'marked';
 
 import * as html from '#html';
-import {escapeRegex, typeAppearance} from '#sugar';
+import {empty, escapeRegex, typeAppearance} from '#sugar';
 import {matchMarkdownLinks} from '#wiki-data';
 
 export const replacerSpec = {
@@ -526,6 +526,7 @@ export function postprocessComments(inputNodes) {
 
 function postprocessHTMLTags(inputNodes, tagName, callback) {
   const outputNodes = [];
+  const errors = [];
 
   const lastNode = inputNodes.at(-1);
 
@@ -593,10 +594,16 @@ function postprocessHTMLTags(inputNodes, tagName, callback) {
           return false;
         })();
 
-        outputNodes.push(
-          callback(attributes, {
-            inline,
-          }));
+        try {
+          outputNodes.push(
+            callback(attributes, {
+              inline,
+            }));
+        } catch (caughtError) {
+          errors.push(new Error(
+            `Failed to process ${match[0]}`,
+            {cause: caughtError}));
+        }
 
         // No longer at the start of a line after the tag - there will at
         // least be text with only '\n' before the next of this tag that's
@@ -619,6 +626,12 @@ function postprocessHTMLTags(inputNodes, tagName, callback) {
     outputNodes.push(node);
   }
 
+  if (!empty(errors)) {
+    throw new AggregateError(
+      errors,
+    `Errors postprocessing <${tagName}> tags`);
+  }
+
   return outputNodes;
 }
 
@@ -628,6 +641,11 @@ export function postprocessImages(inputNodes) {
       const node = {type: 'image'};
 
       node.src = attributes.get('src');
+
+      if (!node.src) {
+        throw new Error('<img> missing src attribute');
+      }
+
       node.inline = attributes.get('inline') ?? inline;
 
       if (attributes.get('link')) node.link = attributes.get('link');
@@ -653,6 +671,10 @@ export function postprocessVideos(inputNodes) {
 
       node.src = attributes.get('src');
 
+      if (!node.src) {
+        throw new Error('<video> missing src attribute');
+      }
+
       if (attributes.get('width')) node.width = parseInt(attributes.get('width'));
       if (attributes.get('height')) node.height = parseInt(attributes.get('height'));
       if (attributes.get('align')) node.align = attributes.get('align');
@@ -668,7 +690,13 @@ export function postprocessAudios(inputNodes) {
       const node = {type: 'audio'};
 
       node.src = attributes.get('src');
+
+      if (!node.src) {
+        throw new Error('<audio> missing src attribute');
+      }
+
       node.inline = attributes.get('inline') ?? inline;
+
       if (attributes.get('align')) node.align = attributes.get('align');
 
       return node;