aboutsummaryrefslogtreecommitdiff
path: root/runtime/doc/develop.txt
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2024-09-24 04:46:50 -0700
committerGitHub <noreply@github.com>2024-09-24 04:46:50 -0700
commit3f6bc34e663c62bc8899dcdc65bf204b2ccfdaec (patch)
tree447732924440ecc91783e26232cd77dc80a1049b /runtime/doc/develop.txt
parent2276743cb8e13483ba15695ef0a1ea65263e825f (diff)
downloadrneovim-3f6bc34e663c62bc8899dcdc65bf204b2ccfdaec.tar.gz
rneovim-3f6bc34e663c62bc8899dcdc65bf204b2ccfdaec.tar.bz2
rneovim-3f6bc34e663c62bc8899dcdc65bf204b2ccfdaec.zip
docs: lua error patterns #30240
Co-authored-by: Mathias Fussenegger <f.mathias@zignar.net> Co-authored-by: Ananth Bhaskararaman <antsub@gmail.com>
Diffstat (limited to 'runtime/doc/develop.txt')
-rw-r--r--runtime/doc/develop.txt43
1 files changed, 30 insertions, 13 deletions
diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt
index 41bb90299b..9dbdaec31c 100644
--- a/runtime/doc/develop.txt
+++ b/runtime/doc/develop.txt
@@ -307,19 +307,36 @@ See also |dev-naming|.
easier to inspect and print, and inherently compatible with all Lua plugins.
(This guideline doesn't apply to opaque, non-data objects like `vim.cmd`.)
- stdlib functions should follow these common patterns:
- - accept iterable instead of table
- - exception: in some cases iterable doesn't make sense, e.g. spair() sorts
- the input by definition, so there is no reason for it to accept an
- iterable, because the input needs to be "reified"; it can't operate on
- a "stream".
- - return iterable instead of table
- - mimic the pairs() or ipairs() interface if the function is intended to be
- used in a "for" loop.
- - when a result-or-error interface is needed, return `result|nil, nil|errmsg`: >
- ---@return Foo|nil # Result object, or nil if not found.
- ---@return nil|string # Error message on failure, or nil on success.
-<
- - Examples: |vim.ui.open()| |io.open()| |luv-error-handling|
+ - Return |lua-result-or-message| (`any|nil,nil|string`) to communicate
+ failure, or choose from |dev-error-patterns| when appropriate.
+ - Accept iterable instead of only table.
+ - Note: in some cases iterable doesn't make sense, e.g. spair() sorts the
+ input by definition, so there is no reason for it to accept an iterable,
+ because the input needs to be "reified"; it can't operate on a "stream".
+ - Return an iterable (generator) instead of table, if possible.
+ - Mimic the pairs() or ipairs() interface if the function is intended for
+ use in a |for-in| loop.
+
+ *dev-error-patterns*
+To communicate failure to a consumer, choose from these patterns (in order of
+preference):
+1. `retval, errmsg`
+ - When failure is normal, or when it is practical for the consumer to
+ continue (fallback) in some other way. See |lua-result-or-message|.
+2. optional result, no errormsg
+ - Special case of 1. When there is only a single case of "doesn't exist"
+ (e.g. cache lookup, dict lookup).
+3. `error("no luck")`
+ - For invalid state ("must not happen"), when failure is exceptional, or at
+ a low level where the consumers are unlikely to handle it in a meaningful
+ way. Advantage is that propagation happens for free and it's harder to
+ accidentally swallow errors. (E.g. using
+ `uv_handle/pipe:write()` without checking return values is common.)
+4. `on_error` parameter
+ - For async and "visitors" traversing a graph, where many errors may be
+ collected while work continues.
+5. `vim.notify` (sometimes with optional `opts.silent` (async, visitors ^))
+ - High-level / application-level messages. End-user invokes these directly.
*dev-patterns*
Interface conventions ~