util/error.lua
author Matthew Wild <mwild1@gmail.com>
Fri, 25 Sep 2020 12:27:45 +0100
changeset 11081 8ea430de5fd3
parent 11080 505c3e5907a5
child 11082 fb3aec3dbe21
permissions -rw-r--r--
util.error: Minor tweaks to error creation code to prepare for future changes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11079
d8fad2b48b05 util.error: Add unique 'instance_id' to error objects
Matthew Wild <mwild1@gmail.com>
parents: 11058
diff changeset
     1
local id = require "util.id";
11055
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     2
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     3
-- Library configuration (see configure())
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     4
local auto_inject_traceback = false;
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     5
local display_tracebacks = false;
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     6
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
     7
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local error_mt = { __name = "error" };
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
function error_mt:__tostring()
11055
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    11
	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
    12
		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
    13
	end
10073
6f317e51544d util.error: Fix traceback due to missing text field
Kim Alvefur <zash@zash.se>
parents: 9753
diff changeset
    14
	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
    15
end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
local function is_err(e)
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
	return getmetatable(e) == error_mt;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
11054
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    21
local function configure(opt)
11055
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    22
	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
    23
		display_tracebacks = opt.display_tracebacks;
08539aa129ee util.error: Add configuration for including traceback in tostring()
Matthew Wild <mwild1@gmail.com>
parents: 11054
diff changeset
    24
	end
11054
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    25
	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
    26
		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
    27
	end
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    28
end
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    29
10497
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    30
-- 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
    31
-- 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
    32
-- 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
    33
-- Translations?
d9132e7412b8 util.error: Write down some thoughts in comments
Kim Alvefur <zash@zash.se>
parents: 10369
diff changeset
    34
-- 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
    35
-- 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
    36
11057
04ad9555c799 util.error: Add a 'source' parameter where origin module can be mentioned
Kim Alvefur <zash@zash.se>
parents: 11055
diff changeset
    37
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
    38
	local template = (registry and registry[e]) or e or {};
11080
505c3e5907a5 util.error: Simplify error creation - remove ability to set context from templates, and remove default context
Matthew Wild <mwild1@gmail.com>
parents: 11079
diff changeset
    39
	context = context or {};
11054
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    40
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    41
	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
    42
		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
    43
	end
51be24b16e8a util.error: Allow optional tracebacks to be injected on errors
Matthew Wild <mwild1@gmail.com>
parents: 10505
diff changeset
    44
11081
8ea430de5fd3 util.error: Minor tweaks to error creation code to prepare for future changes
Matthew Wild <mwild1@gmail.com>
parents: 11080
diff changeset
    45
	local error_instance = setmetatable({
11079
d8fad2b48b05 util.error: Add unique 'instance_id' to error objects
Matthew Wild <mwild1@gmail.com>
parents: 11058
diff changeset
    46
		instance_id = id.short();
11081
8ea430de5fd3 util.error: Minor tweaks to error creation code to prepare for future changes
Matthew Wild <mwild1@gmail.com>
parents: 11080
diff changeset
    47
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
		type = template.type or "cancel";
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
		condition = template.condition or "undefined-condition";
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
		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
    51
		code = template.code;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
11081
8ea430de5fd3 util.error: Minor tweaks to error creation code to prepare for future changes
Matthew Wild <mwild1@gmail.com>
parents: 11080
diff changeset
    53
		context = context;
11057
04ad9555c799 util.error: Add a 'source' parameter where origin module can be mentioned
Kim Alvefur <zash@zash.se>
parents: 11055
diff changeset
    54
		source = source;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
	}, error_mt);
11081
8ea430de5fd3 util.error: Minor tweaks to error creation code to prepare for future changes
Matthew Wild <mwild1@gmail.com>
parents: 11080
diff changeset
    56
8ea430de5fd3 util.error: Minor tweaks to error creation code to prepare for future changes
Matthew Wild <mwild1@gmail.com>
parents: 11080
diff changeset
    57
	return error_instance;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
11058
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    60
local function init(source, registry)
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    61
	return function (e, context)
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    62
		return new(e, context, registry, source);
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    63
	end
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    64
end
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    65
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
local function coerce(ok, err, ...)
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
	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
    68
		return ok, err, ...;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
	local new_err = setmetatable({
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
		native = err;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
		type = "cancel";
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
		condition = "undefined-condition";
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
	}, error_mt);
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
	return ok, new_err, ...;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
end
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
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
    80
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
    81
	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
    82
	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
    83
		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
    84
		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
    85
		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
    86
9361bd1b9c9b util.error: Add a function for creating an error object from an error stanza
Kim Alvefur <zash@zash.se>
parents: 9750
diff changeset
    87
		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
    88
	}, 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
    89
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
    90
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
return {
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
	new = new;
11058
ad07152d7bde util.error: Add a wrapper for common parameters
Kim Alvefur <zash@zash.se>
parents: 11057
diff changeset
    93
	init = init;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
	coerce = coerce;
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
	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
    96
	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
    97
	configure = configure;
9750
848fd204708c util.error: Add new util library for structured errors
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    98
}