diff options
-rw-r--r-- | runtime/doc/api.txt | 17 | ||||
-rw-r--r-- | runtime/doc/develop.txt | 2 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/channel.c | 11 | ||||
-rw-r--r-- | test/functional/api/vim_spec.lua | 10 | ||||
-rw-r--r-- | test/functional/helpers.lua | 8 |
5 files changed, 45 insertions, 3 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index 66fb5bda82..0219488088 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -80,6 +80,19 @@ As Nvim evolves the API may change in compliance with this CONTRACT: - Deprecated functions will not be removed until Nvim version 2.0 ============================================================================== +Global events *api-global-events* + +When a client invokes an API request as an async notification, it is not +possible for Nvim to send an error response. Instead, in case of error, the +following notification will be sent to the client: + + *nvim_error_event* +nvim_error_event[{type}, {message}] + +{type} is a numeric id as defined by `api_info().error_types`, and {message} is +a string with the error message. + +============================================================================== Buffer update events *api-buffer-updates* API clients can "attach" to Nvim buffers to subscribe to buffer update events. @@ -206,7 +219,7 @@ Example using the Nvim python-client: buf.clear_highlight(src) < If the highlights don't need to be deleted or updated, just pass -1 as -src_id (this is the default in python). Use |nvim_buf_clear_highlight()| to +src_id (this is the default in python). Use |nvim_buf_clear_namespace()| to clear highlights from a specific source, in a specific line range or the entire buffer by passing in the line range 0, -1 (the latter is the default in python as used above). @@ -218,7 +231,7 @@ An example of calling the api from vimscript: > call nvim_buf_add_highlight(0, src, "Identifier", 0, 5, -1) " later - call nvim_buf_clear_highlight(0, src, 0, -1) + call nvim_buf_clear_namespace(0, src, 0, -1) > ============================================================================== Global Functions *api-global* diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt index bcf43142ad..2c919f9104 100644 --- a/runtime/doc/develop.txt +++ b/runtime/doc/develop.txt @@ -181,6 +181,8 @@ Standard Features ~ - Clients should call |nvim_set_client_info()| after connecting, so users and plugins can detect the client by handling the |ChanInfo| event. This avoids the need for special variables or other client hints. +- Clients should handle |nvim_error_event| notifications, which will be sent + if an async request to nvim was rejected or caused an error. Package Naming ~ diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 3356cdc61e..46a9e95b91 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -641,7 +641,16 @@ static WBuffer *serialize_response(uint64_t channel_id, { msgpack_packer pac; msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write); - msgpack_rpc_serialize_response(response_id, err, arg, &pac); + if (ERROR_SET(err) && response_id == NO_RESPONSE) { + Array args = ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(err->type)); + ADD(args, STRING_OBJ(cstr_to_string(err->msg))); + msgpack_rpc_serialize_request(0, cstr_as_string("nvim_error_event"), + args, &pac); + api_free_array(args); + } else { + msgpack_rpc_serialize_response(response_id, err, arg, &pac); + } log_server_msg(channel_id, sbuffer); WBuffer *rv = wstream_new_buffer(xmemdup(sbuffer->data, sbuffer->size), sbuffer->size, diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 6261458f2a..ddf5575e31 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -14,6 +14,7 @@ local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed local os_name = helpers.os_name local request = helpers.request local source = helpers.source +local next_msg = helpers.next_msg local expect_err = global_helpers.expect_err local format_string = global_helpers.format_string @@ -46,6 +47,15 @@ describe('API', function() request, nil) end) + it('handles errors in async requests', function() + local error_types = meths.get_api_info()[2].error_types + nvim_async("bogus") + eq({'notification', 'nvim_error_event', + {error_types.Exception.id, 'Invalid method: nvim_bogus'}}, next_msg()) + -- error didn't close channel. + eq(2, eval('1+1')) + end) + describe('nvim_command', function() it('works', function() local fname = helpers.tmpname() diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index db90cb559f..a94e977cd0 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -757,6 +757,14 @@ return function(after_each) end check_logs() check_cores('build/bin/nvim') + if session then + local msg = session:next_message(0) + if msg then + if msg[1] == "notification" and msg[2] == "nvim_error_event" then + error(msg[3][2]) + end + end + end end) end return module |