Repository: chanind/hanzi-writer
Pull request #161 (2020-02-25 19:57:18)

fix: better error message if render target not found
This PR explicitly throws an error `HanziWriter target element not found: <missing id>` when the library is initialized with a non-existent div as the render target. Currently the library will error trying to call `nodeName` of `undefined`, which is a very confusing error.


Patch:
diff --git a/src/renderers/canvas/RenderTarget.js b/src/renderers/canvas/RenderTarget.js
index d7d7a2ad..85bc9f58 100644
--- a/src/renderers/canvas/RenderTarget.js
+++ b/src/renderers/canvas/RenderTarget.js
@@ -15,6 +15,9 @@ RenderTarget.init = (elmOrId, width = '100%', height = '100%') => {
   if (typeof elmOrId === 'string') {
     elm = global.document.getElementById(elmOrId);
   }
+  if (!elm) {
+    throw new Error(`HanziWriter target element not found: ${elmOrId}`);
+  }
   const nodeType = elm.nodeName.toUpperCase();
   if (nodeType === 'CANVAS') {
     canvas = elm;
diff --git a/src/renderers/svg/RenderTarget.js b/src/renderers/svg/RenderTarget.js
index 2ad17824..a8931ea3 100644
--- a/src/renderers/svg/RenderTarget.js
+++ b/src/renderers/svg/RenderTarget.js
@@ -44,6 +44,9 @@ RenderTarget.init = (elmOrId, width = '100%', height = '100%') => {
   if (typeof elmOrId === 'string') {
     elm = global.document.getElementById(elmOrId);
   }
+  if (!elm) {
+    throw new Error(`HanziWriter target element not found: ${elmOrId}`);
+  }
   const nodeType = elm.nodeName.toUpperCase();
   if (nodeType === 'SVG' || nodeType === 'G') {
     svg = elm;


Test patch:
diff --git a/src/__tests__/HanziWriter-test.js b/src/__tests__/HanziWriter-test.js
index eb847a2a..1d7860c6 100644
--- a/src/__tests__/HanziWriter-test.js
+++ b/src/__tests__/HanziWriter-test.js
@@ -83,6 +83,13 @@ describe('HanziWriter', () => {
       });
     });
 
+    it("Errors if the target element can't be found", () => {
+      document.body.innerHTML = '<div id="target"></div>';
+      expect(() => {
+        HanziWriter.create('wrong-target', '人', { charDataLoader });
+      }).toThrow('HanziWriter target element not found: wrong-target');
+    });
+
     it('can optionally use a canvas for rendering instead of SVG', async () => {
       document.body.innerHTML = '<div id="target"></div>';
 
diff --git a/src/renderers/canvas/__tests__/RenderTarget-test.js b/src/renderers/canvas/__tests__/RenderTarget-test.js
index b1789a86..8637d76c 100644
--- a/src/renderers/canvas/__tests__/RenderTarget-test.js
+++ b/src/renderers/canvas/__tests__/RenderTarget-test.js
@@ -4,7 +4,7 @@ const RenderTarget = require('../RenderTarget');
 describe('RenderTarget', () => {
 
   it('can render a canvas into a div on the page', () => {
-    document.body.innerHTML = '<div id="target"></div>';
+    document.body.innerHTML = '<div id="target"></canvas>';
     const target = RenderTarget.init('target', '200px', '120px');
     const canvas = document.querySelector('#target canvas');
     expect(canvas.width).toBe(200);
@@ -13,7 +13,7 @@ describe('RenderTarget', () => {
   });
 
   it('can use an existing canvas on the page', () => {
-    document.body.innerHTML = '<canvas id="target"></div>';
+    document.body.innerHTML = '<canvas id="target"></canvas>';
     const target = RenderTarget.init('target', '200px', '120px');
     const canvas = document.querySelector('canvas#target');
     expect(canvas.width).toBe(200);
@@ -21,4 +21,10 @@ describe('RenderTarget', () => {
     expect(target.node).toBe(canvas);
   });
 
+  it("Errors if the element can't be found", () => {
+    document.body.innerHTML = '<canvas id="target"></canvas>';
+    expect(() => {
+      RenderTarget.init('wrong-target', '200px', '120px');
+    }).toThrow('HanziWriter target element not found: wrong-target');
+  });
 });