util/error.lua
author Kim Alvefur <zash@zash.se>
Fri, 28 Aug 2020 13:55:05 +0200
changeset 11058 ad07152d7bde
parent 11057 04ad9555c799
child 11079 d8fad2b48b05
permissions -rw-r--r--
util.error: Add a wrapper for common parameters Lets you set up source and registry once per module
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11055
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     1
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     2
-- Library configuration (see configure())
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     3
local auto_inject_traceback = false;
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     4
local display_tracebacks = false;
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     5
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     6
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
local error_mt = { __name = "error" };
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
function error_mt:__tostring()
11055
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    10
	if display_tracebacks and self.context.traceback then
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    11
		return ("error<%s:%s:%s:%s>"):format(self.type, self.condition, self.text or "", self.context.traceback);
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    12
	end
10073
6f317e51544d util.error: Fix traceback due to missing text field
Kim Alvefur <zash@zash.se>
parents: 9753
diff changeset
    13
	return ("error<%s:%s:%s>"):format(self.type, self.condition, self.text or "");
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
local function is_err(e)
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
	return getmetatable(e) == error_mt;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
11054
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    20
local function configure(opt)
11055
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    21
	if opt.display_tracebacks ~= nil then
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    22
		display_tracebacks = opt.display_tracebacks;
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    23
	end
11054
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    24
	if opt.auto_inject_traceback ~= nil then
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    25
		auto_inject_traceback = opt.auto_inject_traceback;
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    26
	end
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    27
end
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    28
10497
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    29
-- Do we want any more well-known fields?
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    30
-- Or could we just copy all fields from `e`?
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    31
-- Sometimes you want variable details in the `text`, how to handle that?
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    32
-- Translations?
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    33
-- Should the `type` be restricted to the stanza error types or free-form?
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    34
-- What to set `type` to for stream errors or SASL errors? Those don't have a 'type' attr.
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    35
11057
04ad9555c799 util.error: Add a 'source' parameter where origin module can be mentioned
Kim Alvefur <zash@zash.se>
parents: 11055
diff changeset
    36
local function new(e, context, registry, source)
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
	local template = (registry and registry[e]) or e or {};
11054
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    38
	context = context or template.context or { _error_id = e };
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    39
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    40
	if auto_inject_traceback then
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    41
		context.traceback = debug.traceback("error stack", 2);
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    42
	end
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    43
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
	return setmetatable({
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
		type = template.type or "cancel";
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
		condition = template.condition or "undefined-condition";
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
		text = template.text;
10505
e8186aba1583 util.error: Move default for numeric error code to net.http.server
Kim Alvefur <zash@zash.se>
parents: 10497
diff changeset
    48
		code = template.code;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
		context = context or template.context or { _error_id = e };
11057
04ad9555c799 util.error: Add a 'source' parameter where origin module can be mentioned
Kim Alvefur <zash@zash.se>
parents: 11055
diff changeset
    51
		source = source;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
	}, error_mt);
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
11058
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    55
local function init(source, registry)
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    56
	return function (e, context)
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    57
		return new(e, context, registry, source);
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    58
	end
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    59
end
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    60
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
local function coerce(ok, err, ...)
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
	if ok or is_err(err) then
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
		return ok, err, ...;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
	end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
	local new_err = setmetatable({
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
		native = err;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
		type = "cancel";
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
		condition = "undefined-condition";
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
	}, error_mt);
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
	return ok, new_err, ...;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
9753
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    75
local function from_stanza(stanza, context)
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    76
	local error_type, condition, text = stanza:get_error();
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    77
	return setmetatable({
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    78
		type = error_type or "cancel";
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    79
		condition = condition or "undefined-condition";
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    80
		text = text;
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    81
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    82
		context = context or { stanza = stanza };
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    83
	}, error_mt);
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    84
end
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    85
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
return {
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
	new = new;
11058
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    88
	init = init;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
	coerce = coerce;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
	is_err = is_err;
9753
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    91
	from_stanza = from_stanza;
11054
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    92
	configure = configure;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    93
}