mirror of
https://github.com/nmap/nmap.git
synced 2025-12-22 07:29:01 +00:00
New oops.lua library
Loosely inspired by Rustlang's std::Result type: https://doc.rust-lang.org/beta/std/result/index.html This ought to be easy to use to replace uses of `stdnse.format_output(false, ...)`
This commit is contained in:
129
nselib/oops.lua
Normal file
129
nselib/oops.lua
Normal file
@@ -0,0 +1,129 @@
|
||||
--- Useful error stack objects
|
||||
--
|
||||
-- Many NSE library functions return a boolean status and an optional error
|
||||
-- message. The Oops library consists of several simple functions to accumulate
|
||||
-- these errors and pass them up the stack, resulting in a useful and verbose
|
||||
-- error message when debugging.
|
||||
--
|
||||
-- @author Daniel Miller
|
||||
-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
|
||||
-- @class module
|
||||
-- @name oops
|
||||
|
||||
local require = require
|
||||
local setmetatable = setmetatable
|
||||
local _ENV = require "strict" {}
|
||||
|
||||
local nmap = require "nmap"
|
||||
local debugging = nmap.debugging
|
||||
local verbosity = nmap.verbosity
|
||||
|
||||
local table = require "table"
|
||||
local concat = table.concat
|
||||
local insert = table.insert
|
||||
|
||||
local Oops = {
|
||||
new = function (self, message)
|
||||
local o = {message}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end,
|
||||
|
||||
push = function (self, message)
|
||||
insert(self, 1, message)
|
||||
end,
|
||||
|
||||
__tostring = function (self)
|
||||
local banner = "The script encountered an error"
|
||||
local sep = ":\n- "
|
||||
if debugging() > 0 then
|
||||
-- Print full error trace
|
||||
return banner .. sep .. concat(self, sep)
|
||||
end
|
||||
if verbosity() > 0 then
|
||||
-- Show just the top error
|
||||
return banner .. ": " .. self[1]
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
--- Add an error message to a stack of errors
|
||||
--
|
||||
-- @param message The error message to add to the stack.
|
||||
-- @param previous (Optional) Any error reported by other functions that failed.
|
||||
-- @return An Oops object representing the error stack.
|
||||
err = function (message, previous)
|
||||
local result
|
||||
if previous then
|
||||
if previous.push then
|
||||
result = previous
|
||||
else
|
||||
result = Oops:new(previous)
|
||||
end
|
||||
result:push(message)
|
||||
elseif message.push then
|
||||
result = message
|
||||
else
|
||||
result = Oops:new(message)
|
||||
end
|
||||
return result
|
||||
end
|
||||
local err = err
|
||||
|
||||
--- Report an error or return a good value
|
||||
--
|
||||
-- If the status is true, just return the message. If it's false, return the
|
||||
-- message as an Oops object. This can be easily used as the final return value
|
||||
-- of a script.
|
||||
-- @param status The return status of the script.
|
||||
-- @param message The output of the script, or an error message if status is false.
|
||||
-- @return The message if status is true, or an error message if it is false.
|
||||
output = function (status, message)
|
||||
if status then
|
||||
return message
|
||||
else
|
||||
return err(message)
|
||||
end
|
||||
end
|
||||
local output = output
|
||||
|
||||
--- Report a status and error or return values
|
||||
--
|
||||
-- This is intended to wrap a function that returns a status and either an
|
||||
-- error or some value. If the status is false, the message is added to the
|
||||
-- stack of errors. Instead of this code:
|
||||
--
|
||||
-- <code>
|
||||
-- local status, value_or_error, value = somefunction(args)
|
||||
-- if not status then
|
||||
-- return status, "somefunction failed for some reason"
|
||||
-- end
|
||||
-- </code>
|
||||
--
|
||||
-- with this instead:
|
||||
--
|
||||
-- <code>
|
||||
-- local status, value_or_error, value = oops.raise("somefunction failed", somefunction(args))
|
||||
-- if not status then
|
||||
-- return status, value_or_error
|
||||
-- end
|
||||
-- </code>
|
||||
--
|
||||
-- but instead of just the one error, you get a stack of errors from
|
||||
-- <code>somefunction</code> with your own message at the top.
|
||||
--
|
||||
-- @param message The error message to report if status is false.
|
||||
-- @param status The first return value of the function. Treated as boolean, but returned unmodified.
|
||||
-- @param previous The second return value of the function, or error.
|
||||
-- @return The same status that was input.
|
||||
-- @return The rest of the return values, but on error, the message will be added to the stack.
|
||||
raise = function (message, status, previous, ...)
|
||||
local r = previous
|
||||
if not status then
|
||||
r = err(message, previous)
|
||||
end
|
||||
return status, r, ...
|
||||
end
|
||||
|
||||
return _ENV
|
||||
Reference in New Issue
Block a user