aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2020-12-09 13:55:10 +0000
committerMatthew Wild <mwild1@gmail.com>2020-12-09 13:55:10 +0000
commite875910c5db89d3f1752b878357f0a164a1936a2 (patch)
tree1b1f3de5bdfcbc5c0d94f33fa947717ca41eba97
parent3de8b69f1cea1bbfdc29dceb4ca1991d583dcc74 (diff)
downloadprosody-e875910c5db89d3f1752b878357f0a164a1936a2.tar.gz
prosody-e875910c5db89d3f1752b878357f0a164a1936a2.zip
util.error: Add coerce and wrap methods to registry(?) objects
-rw-r--r--spec/util_error_spec.lua70
-rw-r--r--util/error.lua19
2 files changed, 89 insertions, 0 deletions
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