diff options
author | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2013-10-08 18:50:56 +0300 |
---|---|---|
committer | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2013-10-08 18:50:56 +0300 |
commit | 33728ad3382d74281412d4556561d479bb88832b (patch) | |
tree | e8a9b2798dec96d820715f729989e91f9e7d5e12 /acf2/error.lua | |
parent | 3e48dd63e8bdf0c2641cfb73e6b20bea8c466ff8 (diff) | |
download | aconf-33728ad3382d74281412d4556561d479bb88832b.tar.bz2 aconf-33728ad3382d74281412d4556561d479bb88832b.tar.xz |
changed module paths from acf to acf2v0.1.0
Diffstat (limited to 'acf2/error.lua')
-rw-r--r-- | acf2/error.lua | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/acf2/error.lua b/acf2/error.lua new file mode 100644 index 0000000..14a2570 --- /dev/null +++ b/acf2/error.lua @@ -0,0 +1,99 @@ +--[[ +Copyright (c) 2012-2013 Kaarle Ritvanen +See LICENSE file for license details +--]] + +local M = {} + +local object = require('acf2.object') +local class = object.class + +local util = require('acf2.util') + +local json = require('cjson') + + +local ErrorTable = class() + +function ErrorTable:init() self.errors = {} end + +function ErrorTable:success() return not next(self.errors) end + +function ErrorTable:raise() + if not self:success() then error(json.encode(self.errors)) end +end + + +local ErrorList = class(ErrorTable) + +function ErrorList:init(label) + object.super(self, ErrorList):init() + self.label = label +end + +function ErrorList:insert(msg) + table.insert(util.setdefault(self.errors, self.label, {}), msg) +end + + +M.ErrorDict = class(ErrorTable) + +function M.ErrorDict:collect(func, ...) + local function pack(success, ...) + local arg = {...} + return success, success and arg or arg[1] + end + + local arg = {...} + local success, res = pack( + xpcall( + function() return func(unpack(arg)) end, + function(err) + local _, _, data = err:find('.-: (.+)') + local success, res = pcall(json.decode, data) + if success and type(res) == 'table' then return res end + return data..'\n'..debug.traceback() + end + ) + ) + + if success then return unpack(res) end + + if type(res) == 'table' then + for label, errors in pairs(res) do + for _, err in ipairs(errors) do + table.insert(util.setdefault(self.errors, label, {}), err) + end + end + else error(res) end +end + + +function M.raise(label, msg) + local err = ErrorList(label) + err:insert(msg) + err:raise() +end + +function M.relabel(label, ...) + local err = M.ErrorDict() + local res = {err:collect(...)} + if err:success() then return unpack(res) end + + elist = ErrorList(label) + for lbl, el in pairs(err.errors) do + for _, e in ipairs(el) do elist:insert(lbl..': '..e) end + end + elist:raise() +end + +function M.call(...) + local err = M.ErrorDict() + local res = {err:collect(...)} + if err:success() then return true, unpack(res) end + if err.errors.system then error(err.errors.system[1]) end + return false, err.errors +end + + +return M |