From 167a2383b9966ac227a77b0221088246e14ce75a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 16 Dec 2024 04:00:20 -0800 Subject: fix(api): not using TRY_WRAP, generic error messages #31595 Problem: - API functions using `try_start` directly instead of `TRY_WRAP`, do not surface the underlying error message, and instead show generic things like "Failed to set buffer". - Error handling code is duplicated in the API impl, instead of delegating to the vim buffer/window handling logic. Solution: - Use `TRY_WRAP`. --- src/nvim/api/private/helpers.c | 9 +++++---- src/nvim/api/vim.c | 19 +++++-------------- src/nvim/api/window.c | 7 +------ 3 files changed, 11 insertions(+), 24 deletions(-) (limited to 'src/nvim/api') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 8ddaecc58e..5bf66a092f 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -101,9 +101,9 @@ bool try_leave(const TryState *const tstate, Error *const err) return ret; } -/// Start block that may cause vimscript exceptions +/// Starts a block that may cause Vimscript exceptions; must be mirrored by `try_end()` call. /// -/// Each try_start() call should be mirrored by try_end() call. +/// Note: use `TRY_WRAP` instead (except in `FUNC_API_FAST` functions such as nvim_get_runtime_file). /// /// To be used as a replacement of `:try … catch … endtry` in C code, in cases /// when error flag could not already be set. If there may be pending error @@ -114,8 +114,9 @@ void try_start(void) trylevel++; } -/// End try block, set the error message if any and return true if an error -/// occurred. +/// Ends a `try_start` block; sets error message if any and returns true if an error occurred. +/// +/// Note: use `TRY_WRAP` instead (except in `FUNC_API_FAST` functions such as nvim_get_runtime_file). /// /// @param err Pointer to the stack-allocated error object /// @return true if an error occurred diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 42fc21deac..1acfa0d34b 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -596,6 +596,7 @@ ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Arena *arena, Er int flags = DIP_DIRFILE | (all ? DIP_ALL : 0); TryState tstate; + // XXX: intentionally not using `TRY_WRAP`, to avoid `did_emsg=false` in `try_end`. try_enter(&tstate); do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie); vim_ignored = try_leave(&tstate, err); @@ -888,23 +889,13 @@ void nvim_set_current_buf(Buffer buffer, Error *err) { buf_T *buf = find_buffer_by_handle(buffer, err); - if (!buf || curwin->w_buffer == buf) { - return; - } - - if (curwin->w_p_wfb) { - api_set_error(err, kErrorTypeException, "%s", e_winfixbuf_cannot_go_to_buffer); + if (!buf) { return; } - try_start(); - int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0); - if (!try_end(err) && result == FAIL) { - api_set_error(err, - kErrorTypeException, - "Failed to switch to buffer %d", - buffer); - } + TRY_WRAP(err, { + do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0); + }); } /// Gets the current list of window handles. diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index f415415fa7..170d5c6cdb 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -59,12 +59,7 @@ void nvim_win_set_buf(Window window, Buffer buffer, Error *err) { win_T *win = find_window_by_handle(window, err); buf_T *buf = find_buffer_by_handle(buffer, err); - if (!win || !buf || win->w_buffer == buf) { - return; - } - - if (win->w_p_wfb) { - api_set_error(err, kErrorTypeException, "%s", e_winfixbuf_cannot_go_to_buffer); + if (!win || !buf) { return; } -- cgit