From 73fb0ea926cf27f2107dfa1138f74a1f7999694d Mon Sep 17 00:00:00 2001 From: William Boman Date: Sat, 3 Sep 2022 01:26:03 +0200 Subject: fix(EventEmitter): properly deregister handlers, print errors that occur in handler (#373) --- lua/mason-core/EventEmitter.lua | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'lua/mason-core/EventEmitter.lua') diff --git a/lua/mason-core/EventEmitter.lua b/lua/mason-core/EventEmitter.lua index 5d7aeaa0..403628a0 100644 --- a/lua/mason-core/EventEmitter.lua +++ b/lua/mason-core/EventEmitter.lua @@ -1,3 +1,4 @@ +local log = require "mason-core.log" ---@class EventEmitter ---@field private __event_handlers table> ---@field private __event_handlers_once table> @@ -13,19 +14,32 @@ function EventEmitter.init(obj) return obj end +---@param event any +---@param handler fun(...): any +local function call_handler(event, handler, ...) + local ok, err = pcall(handler, ...) + if not ok then + vim.schedule(function() + log.fmt_warn("EventEmitter handler failed for event %s with error %s", event, err) + vim.api.nvim_err_writeln(err) + end) + end +end + ---@param event any function EventEmitter:emit(event, ...) if self.__event_handlers[event] then for handler in pairs(self.__event_handlers[event]) do - pcall(handler, ...) + call_handler(event, handler, ...) end end if self.__event_handlers_once[event] then for handler in pairs(self.__event_handlers_once[event]) do - pcall(handler, ...) - self.__event_handlers_once[handler] = nil + call_handler(event, handler, ...) + self.__event_handlers_once[event][handler] = nil end end + return self end ---@param event any @@ -35,6 +49,7 @@ function EventEmitter:on(event, handler) self.__event_handlers[event] = {} end self.__event_handlers[event][handler] = handler + return self end ---@param event any @@ -44,16 +59,19 @@ function EventEmitter:once(event, handler) self.__event_handlers_once[event] = {} end self.__event_handlers_once[event][handler] = handler + return self end ---@param event any ---@param handler fun(payload: any) function EventEmitter:off(event, handler) - if vim.tbl_get(self.__event_handlers, { event, handler }) then + if self.__event_handlers[event] then self.__event_handlers[event][handler] = nil - return true end - return false + if self.__event_handlers_once[event] then + self.__event_handlers_once[event][handler] = nil + end + return self end ---@private