minor refactor of router to use explicit exceptions
authorJustin Wind <justin.wind+git@gmail.com>
Sat, 26 Aug 2023 19:39:54 +0000 (12:39 -0700)
committerJustin Wind <justin.wind+git@gmail.com>
Sat, 26 Aug 2023 19:43:59 +0000 (12:43 -0700)
lib/dingus.js
lib/errors.js
lib/router/index.js
test/lib/router.js

index 5b4643c6b2e79c641c3604910c0a3397be56da6b..484debced43f0732a71ca0967d964b6475256a29 100644 (file)
@@ -13,7 +13,7 @@ const querystring = require('querystring');
 const common = require('./common');
 const ContentNegotiation = require('./content-negotiation');
 const Enum = require('./enum');
-const { DingusError, ResponseError } = require('./errors');
+const { DingusError, ResponseError, RouterNoMethodError, RouterNoPathError } = require('./errors');
 const { extensionToMime } = require('./mime-helper');
 const Router = require('./router');
 const Template = require('./template');
@@ -268,18 +268,13 @@ class Dingus {
     try {
       ({ handler, handlerArgs } = this.router.lookup(req.method, pathPart, ctx));
     } catch (e) {
-      if (e instanceof DingusError) {
-        switch (e.message) {
-          case 'NoPath':
-            handler = this.handlerNotFound.bind(this);
-            break;
-          case 'NoMethod':
-            handler = this.handlerMethodNotAllowed.bind(this);
-            break;
-          default:
-            this.logger.error(_scope, 'unknown dingus error', { error: e });
-            handler = this.handlerInternalServerError.bind(this);
-        }
+      if (e instanceof RouterNoPathError) {
+        handler = this.handlerNotFound.bind(this);
+      } else if (e instanceof RouterNoMethodError) {
+        handler = this.handlerMethodNotAllowed.bind(this);
+      } else if (e instanceof DingusError) {
+        this.logger.error(_scope, 'unknown dingus error', { error: e });
+        handler = this.handlerInternalServerError.bind(this);
       } else if (e instanceof URIError) {
         handler = this.handlerBadRequest.bind(this);
       } else {
index ed5b151461060215146bdcfdccacafce9fe76c1a..942ecc0f684656059f4e0fad66288db7c57f2647 100644 (file)
@@ -22,7 +22,23 @@ class ResponseError extends DingusError {
   }
 }
 
+class RouterError extends DingusError {
+  constructor(...args) {
+    super(...args);
+    delete this.stack;
+  }
+}
+
+class RouterNoPathError extends RouterError {
+}
+
+class RouterNoMethodError extends RouterError {
+}
+
 module.exports = {
   DingusError,
   ResponseError,
+  RouterError,
+  RouterNoPathError,
+  RouterNoMethodError,
 };
index 1585065e14ce79b804cd6de967965951ab0d535a..fd19bdf5192cfd9efd7b4c00023f1ae92265cbd1 100644 (file)
@@ -7,7 +7,7 @@
 
 const { METHODS: httpMethods } = require('http');
 const common = require('../common');
-const { DingusError } = require('../errors');
+const { DingusError, RouterNoPathError, RouterNoMethodError } = require('../errors');
 const PathParameter = require('./path-parameter');
 
 // Internal identifiers for route entries.
@@ -266,10 +266,10 @@ class Router {
       if ('*' in matchedPath[kPathMethods]) {
         return matchedPath[kPathMethods]['*'];
       }
-      throw new DingusError('NoMethod');
+      throw new RouterNoMethodError();
     }
     ctx.unmatchedPath = pathParts;
-    throw new DingusError('NoPath');
+    throw new RouterNoPathError();
   }
 
 
index 8a9d1e26f8e1e502cc5b0e164bb78d56ec457785..bcb45f2d00bbfacad8bb33c5fe593cbfce6183b5 100644 (file)
@@ -6,7 +6,7 @@ const assert = require('assert');
 const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require
 const Router = require('../../lib/router');
 const PathParameter = require('../../lib/router/path-parameter');
-const { DingusError } = require('../../lib/errors');
+const { DingusError, RouterNoPathError, RouterNoMethodError } = require('../../lib/errors');
 
 const noExpectedException = 'did not get expected exception';
 
@@ -311,8 +311,7 @@ describe('Router', function () {
         router.lookup(method, path, ctx);
         assert.fail(noExpectedException);
       } catch (e) {
-        assert(e instanceof DingusError);
-        assert.strictEqual(e.message, 'NoPath');
+        assert(e instanceof RouterNoPathError);
       }
     });
     it('finds handler', function () {
@@ -353,8 +352,7 @@ describe('Router', function () {
         router.lookup(method, path, ctx);
         assert.fail(noExpectedException);
       } catch (e) {
-        assert(e instanceof DingusError);
-        assert.strictEqual(e.message, 'NoMethod');
+        assert(e instanceof RouterNoMethodError);
       }
     });
     it('does not lookup non-existent path', async function () {
@@ -365,8 +363,7 @@ describe('Router', function () {
         router.lookup(method, path, ctx);
         assert.fail(noExpectedException);
       } catch (e) {
-        assert(e instanceof DingusError);
-        assert.strictEqual(e.message, 'NoPath');
+        assert(e instanceof RouterNoPathError);
       }
     });