Merge pull request #9300 from bfredl/asyncerr

rpc: fix invalid responses, turn errors from async calls into notifications
This commit is contained in:
Björn Linse 2018-12-03 13:00:41 +01:00 committed by GitHub
commit 231de72539
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 3 deletions

View File

@ -79,6 +79,19 @@ As Nvim evolves the API may change in compliance with this CONTRACT:
- Existing items will not be removed (after release).
- 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*
@ -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*

View File

@ -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 ~

View File

@ -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,

View File

@ -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()

View File

@ -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