nvim/util: report mload module errors
This commit unclobbers syntax and other errors that can occur when loading a module. Previously, we just pcall/2'd any inputs and silently assumed that any error reported meant the module didn't exist. The changes within add a third branch to the mix: EXISTS, NOT_FOUND, and LOAD_ERR. We keep the previous behaviour of not throwing when an error is detected, but we do print out a big, red, angry message now. As a side note, this should also slightly improve performance, due to less errors being thrown; on account of us manually detecting whether a module exists or not.
This commit is contained in:
parent
6e8bbd4e22
commit
ff33cf52d9
|
@ -1,6 +1,29 @@
|
|||
|
||||
local M = {}
|
||||
|
||||
---@enum Code
|
||||
local Code = { EXISTS = 1, NOT_FOUND = 0, LOAD_ERR = -1 }
|
||||
|
||||
--- Checks if the given module exists, and adds it to the preload
|
||||
--- list if it does.
|
||||
---@param module string
|
||||
---@return boolean
|
||||
local function module_exists(module)
|
||||
if package.loaded[module] then return true end
|
||||
|
||||
for _, searcher in ipairs(package.loaders or package.searchers) do
|
||||
local fn = searcher(module)
|
||||
|
||||
if type(fn) == 'function' then
|
||||
package.preload[module] = fn
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- Reload a given module, returning the result of loading it.
|
||||
function M.mreload(module)
|
||||
if package.loaded[module] then
|
||||
|
@ -10,9 +33,21 @@ function M.mreload(module)
|
|||
return require(module)
|
||||
end
|
||||
|
||||
-- Try reloading the given module, returning ok, module
|
||||
--- Try reloading the given module, returning (code, module|error)
|
||||
--- Returns enumerated:
|
||||
--- - Code.EXISTS, module
|
||||
--- - Code.NOT_FOUND, nil
|
||||
--- - Code.LOAD_ERR, error
|
||||
---@param module string
|
||||
---@return Code, any|string
|
||||
function M.try_mreload(module)
|
||||
return pcall(M.mreload, module)
|
||||
if module_exists(module) then
|
||||
local ok, result = pcall(M.mreload, module)
|
||||
|
||||
return ok and Code.EXISTS or Code.LOAD_ERR, result
|
||||
else
|
||||
return Code.NOT_FOUND, nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Try reloading the given config module, returning either
|
||||
|
@ -25,8 +60,10 @@ end
|
|||
-- 4. fn() --> table
|
||||
--
|
||||
-- It the latter cases, *configuration will not be reloaded*, this is
|
||||
-- primaraily meant for inline, static configuration
|
||||
-- primarily meant for inline, static configuration
|
||||
function M.try_mconfig(module)
|
||||
-- Check if we were handed a object or function
|
||||
-- instead of a module string
|
||||
if type(module) ~= "string" then
|
||||
module = type(module) == "function" and module() or module
|
||||
module = type(module) == "table" and module or {}
|
||||
|
@ -34,10 +71,25 @@ function M.try_mconfig(module)
|
|||
return module
|
||||
end
|
||||
|
||||
local ok, config = M.try_mreload(module)
|
||||
config = type(config) == "function" and config() or config
|
||||
-- We definitely have a module string, try loading it
|
||||
local c, config = M.try_mreload(module)
|
||||
|
||||
return (ok and type(config) == "table") and config or {}
|
||||
if c == Code.NOT_FOUND then
|
||||
return {}
|
||||
elseif c == Code.EXISTS then
|
||||
return type(config) == "function" and config() or config
|
||||
elseif c == Code.LOAD_ERR then
|
||||
local options = {
|
||||
title = string.format('Module Load Error: %s', module),
|
||||
timeout = 2000
|
||||
}
|
||||
vim.notify_once(config, vim.log.levels.ERROR, options)
|
||||
|
||||
return {}
|
||||
end
|
||||
|
||||
-- Catch fall through in case we ever add another Code variant
|
||||
error(string.format("try_mconfig/1: unhandled Code '%s'", c))
|
||||
end
|
||||
|
||||
-- Retrieve the config table stored in the provided module,
|
||||
|
|
Loading…
Reference in New Issue