diff options
| author | William Boman <william@redwill.se> | 2022-03-02 20:13:26 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-02 20:13:26 +0100 |
| commit | ac04f507f83f178ad563426cfa0d0d4f0e984ecc (patch) | |
| tree | 90c94ed076ec3abe30b178b0f9d9fc0fdd036e18 | |
| parent | run autogen_metadata.lua (diff) | |
| download | mason-ac04f507f83f178ad563426cfa0d0d4f0e984ecc.tar mason-ac04f507f83f178ad563426cfa0d0d4f0e984ecc.tar.gz mason-ac04f507f83f178ad563426cfa0d0d4f0e984ecc.tar.bz2 mason-ac04f507f83f178ad563426cfa0d0d4f0e984ecc.tar.lz mason-ac04f507f83f178ad563426cfa0d0d4f0e984ecc.tar.xz mason-ac04f507f83f178ad563426cfa0d0d4f0e984ecc.tar.zst mason-ac04f507f83f178ad563426cfa0d0d4f0e984ecc.zip | |
fix(async): pcall callback-style functions to catch errors (#515)
| -rw-r--r-- | lua/nvim-lsp-installer/core/async/init.lua | 27 | ||||
| -rw-r--r-- | tests/core/async_spec.lua | 14 |
2 files changed, 32 insertions, 9 deletions
diff --git a/lua/nvim-lsp-installer/core/async/init.lua b/lua/nvim-lsp-installer/core/async/init.lua index a9c1704c..1dd2c138 100644 --- a/lua/nvim-lsp-installer/core/async/init.lua +++ b/lua/nvim-lsp-installer/core/async/init.lua @@ -6,15 +6,23 @@ local Promise = {} Promise.__index = Promise function Promise.new(resolver) - return setmetatable({ resolver = resolver }, Promise) + return setmetatable({ resolver = resolver, has_resolved = false }, Promise) +end + +---@param success boolean +---@param cb fun() +function Promise:_wrap_resolver_cb(success, cb) + return function(...) + if self.has_resolved then + return + end + self.has_resolved = true + cb(success, ...) + end end function Promise:__call(callback) - self.resolver(function(...) - callback(true, ...) - end, function(...) - callback(false, ...) - end) + self.resolver(self:_wrap_resolver_cb(true, callback), self:_wrap_resolver_cb(false, callback)) end local function await(resolver) @@ -28,9 +36,12 @@ end local function promisify(async_fn) return function(...) local args = table_pack(...) - return await(function(resolve) + return await(function(resolve, reject) args[args.n + 1] = resolve - async_fn(unpack(args, 1, args.n + 1)) + local ok, err = pcall(async_fn, unpack(args, 1, args.n + 1)) + if not ok then + reject(err) + end end) end end diff --git a/tests/core/async_spec.lua b/tests/core/async_spec.lua index 42c1fe65..7d965e9b 100644 --- a/tests/core/async_spec.lua +++ b/tests/core/async_spec.lua @@ -1,5 +1,6 @@ local assert = require "luassert" local spy = require "luassert.spy" +local match = require "luassert.match" local a = require "nvim-lsp-installer.core.async" local process = require "nvim-lsp-installer.process" @@ -15,7 +16,7 @@ describe("async", function() a.sleep(1000) end) local stop = timestamp() - local grace_ms = 5 + local grace_ms = 25 assert.is_true((stop - start) >= (1000 - grace_ms)) end) @@ -47,4 +48,15 @@ describe("async", function() assert.spy(james_bond).was_not.called() end) ) + + it( + "should reject if async function raises error", + async_test(function() + local ok, err = a.promisify(function() + error "something went wrong" + end)() + assert.is_false(ok) + assert.is_true(match.has_match "something went wrong$"(err)) + end) + ) end) |
