From e875910c5db89d3f1752b878357f0a164a1936a2 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 9 Dec 2020 13:55:10 +0000 Subject: util.error: Add coerce and wrap methods to registry(?) objects --- spec/util_error_spec.lua | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ util/error.lua | 19 +++++++++++++ 2 files changed, 89 insertions(+) diff --git a/spec/util_error_spec.lua b/spec/util_error_spec.lua index 34edd313..be176635 100644 --- a/spec/util_error_spec.lua +++ b/spec/util_error_spec.lua @@ -140,6 +140,76 @@ describe("util.error", function () nope = {type = "auth"; condition = "not-authorized"; text = "Can't let you do that Dave"}; }, compact2.registry); end); + + describe(".wrap", function () + local reg = errors.init("test", "spec", { + myerror = { "cancel", "internal-server-error", "Oh no" }; + }); + it("is exposed", function () + assert.is_function(reg.wrap); + end); + it("returns errors according to the registry", function () + local e = reg.wrap("myerror"); + assert.equal("cancel", e.type); + assert.equal("internal-server-error", e.condition); + assert.equal("Oh no", e.text); + end); + + it("passes through existing errors", function () + local e = reg.wrap(reg.new({ type = "auth", condition = "forbidden" })); + assert.equal("auth", e.type); + assert.equal("forbidden", e.condition); + end); + + it("wraps arbitrary values", function () + local e = reg.wrap(123); + assert.equal("cancel", e.type); + assert.equal("undefined-condition", e.condition); + assert.equal(123, e.context.wrapped_error); + end); + end); + + describe(".coerce", function () + local reg = errors.init("test", "spec", { + myerror = { "cancel", "internal-server-error", "Oh no" }; + }); + + it("is exposed", function () + assert.is_function(reg.coerce); + end); + + it("passes through existing errors", function () + local function test() + return nil, errors.new({ type = "auth", condition = "forbidden" }); + end + local ok, err = reg.coerce(test()); + assert.is_nil(ok); + assert.is_truthy(errors.is_err(err)); + assert.equal("forbidden", err.condition); + end); + + it("passes through successful return values", function () + local function test() + return 1, 2, 3, 4; + end + local one, two, three, four = reg.coerce(test()); + assert.equal(1, one); + assert.equal(2, two); + assert.equal(3, three); + assert.equal(4, four); + end); + + it("wraps non-error objects", function () + local function test() + return nil, "myerror"; + end + local ok, err = reg.coerce(test()); + assert.is_nil(ok); + assert.is_truthy(errors.is_err(err)); + assert.equal("internal-server-error", err.condition); + assert.equal("Oh no", err.text); + end); + end); end); end); diff --git a/util/error.lua b/util/error.lua index ed3ef4f4..173d4b7d 100644 --- a/util/error.lua +++ b/util/error.lua @@ -98,12 +98,31 @@ local function init(source, namespace, registry) if protoerr and type(next(protoerr)) == "number" then registry = expand_registry(namespace, registry); end + + local function wrap(e, context) + if is_err(e) then + return e; + end + local err = new(registry[e] or { + type = "cancel", condition = "undefined-condition" + }, context, registry, source); + err.context.wrapped_error = e; + return err; + end + return { source = source; registry = registry; new = function (e, context) return new(e, context, registry, source); end; + coerce = function (ok, err, ...) + if ok then + return ok, err, ...; + end + return nil, wrap(err); + end; + wrap = wrap; }; end -- cgit v1.2.3