diff --git a/errors.lua b/errors.lua index 4498b88..0b1baab 100644 --- a/errors.lua +++ b/errors.lua @@ -1,8 +1,40 @@ -local string_dist = require 'string_distance' +local string_dist +do + local thispath = ... and select('1', ...):match('.+%.') or '' + local function import (name, ignore_failure) + local was_loaded, lib_or_error = pcall(require, thispath..name) + if not was_loaded then + if ignore_failure then return nil end + error('['..thispath..']: Could not load vital library: '..name..'.lua:\n\t'..lib_or_error) + end + return lib_or_error + end + + string_dist = import 'string_distance' +end + assert(debug and debug.getinfo) +-------------------------------------------------------------------------------- +-- Util + +local function format_probable_strings (probable_strings, amount) + assert(type(probable_strings) == 'table') + assert(type(amount) == 'number') + assert(#probable_strings > 0) + + local l = {} + for i = 1, math.min(amount, #probable_strings) do + l[#l+1] = probable_strings[i] + l[#l+1] = ', ' + end + if l[#l] == ', ' then l[#l] = nil end + if #l >= 3 then l[#l-1] = ' or ' end + return table.concat(l, '') +end + -------------------------------------------------------------------------------- -- Error handler @@ -35,20 +67,37 @@ function ErrorHandler:getErrorFunc (mode, name) -- Create error funcs. if mode == 'internal' then return function (format_msg, ...) - error(('[%s%s]: '..format_msg):format(self.module_name, name, ...), 2) + assert(type(format_msg) == 'string') + return error(('[%s%s]: '..format_msg):format(self.module_name, name, ...), 2) end elseif mode == 'external' then return function (format_msg, ...) + assert(type(format_msg) == 'string') local level = 2 while self.registered[debug.getinfo(level, 'f').func] do level = level + 1 end - error(('[%s%s]: '..format_msg):format(self.module_name, name, ...), level) + return error(('[%s%s]: '..format_msg):format(self.module_name, name, ...), level) end end assert(false) end +function ErrorHandler:attemptCorrection (format_msg, gotten_string, probable_strings) + assert(type(self) == 'table', 'Wow, mister, remember to call with OO notation.') + assert(type(format_msg) == 'string') + assert(type(gotten_string) == 'string') + assert(type(probable_strings) == 'table') + + local probable_strings = string_dist.strings_with_highest_similarity(gotten_string, probable_strings) + local list_string = format_probable_strings(probable_strings, 3) + return self:getErrorFunc('internal', '')(format_msg, gotten_string, list_string) +end + +function ErrorHandler:__call (format_msg, ...) + return self:getErrorFunc('internal')(format_msg, ...) +end + -------------------------------------------------------------------------------- return {