aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-06-05 13:16:25 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-06-05 13:16:25 -0300
commitb4d5dff8ec4f1c8a44db66d368e95d359b04aea7 (patch)
treee87fbd3bcbf8a271429ee31f32eaf928058ab376 /testes
parent14edd364c3abcb758e74c68a2bdd4ddaeefdae2a (diff)
downloadlua-b4d5dff8ec4f1c8a44db66d368e95d359b04aea7.tar.gz
lua-b4d5dff8ec4f1c8a44db66d368e95d359b04aea7.tar.bz2
lua-b4d5dff8ec4f1c8a44db66d368e95d359b04aea7.zip
Multiple errors in '__toclose' report the first one
When there are multiple errors when closing objects, the error reported by the protected call is the first one, for two reasons: First, other errors may be caused by this one; second, the first error is handled in the original execution context, and therefore has the full traceback.
Diffstat (limited to 'testes')
-rw-r--r--testes/coroutine.lua10
-rw-r--r--testes/locals.lua37
2 files changed, 33 insertions, 14 deletions
diff --git a/testes/coroutine.lua b/testes/coroutine.lua
index 198a5870..f2c0da8b 100644
--- a/testes/coroutine.lua
+++ b/testes/coroutine.lua
@@ -163,15 +163,23 @@ do
163 assert(not X and coroutine.status(co) == "dead") 163 assert(not X and coroutine.status(co) == "dead")
164 164
165 -- error closing a coroutine 165 -- error closing a coroutine
166 local x = 0
166 co = coroutine.create(function() 167 co = coroutine.create(function()
168 local <toclose> y = func2close(function (self,err)
169 if (err ~= 111) then os.exit(false) end -- should not happen
170 x = 200
171 error(200)
172 end)
167 local <toclose> x = func2close(function (self, err) 173 local <toclose> x = func2close(function (self, err)
168 assert(err == nil); error(111) 174 assert(err == nil); error(111)
169 end) 175 end)
170 coroutine.yield() 176 coroutine.yield()
171 end) 177 end)
172 coroutine.resume(co) 178 coroutine.resume(co)
179 assert(x == 0)
173 local st, msg = coroutine.close(co) 180 local st, msg = coroutine.close(co)
174 assert(not st and coroutine.status(co) == "dead" and msg == 111) 181 assert(st == false and coroutine.status(co) == "dead" and msg == 111)
182 assert(x == 200)
175 183
176end 184end
177 185
diff --git a/testes/locals.lua b/testes/locals.lua
index 7834d7da..dccda28f 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -267,14 +267,14 @@ do -- errors in __close
267 if err then error(4) end 267 if err then error(4) end
268 end 268 end
269 local stat, msg = pcall(foo, false) 269 local stat, msg = pcall(foo, false)
270 assert(msg == 1) 270 assert(msg == 3)
271 assert(log[1] == 10 and log[2] == 3 and log[3] == 2 and log[4] == 2 271 assert(log[1] == 10 and log[2] == 3 and log[3] == 3 and log[4] == 3
272 and #log == 4) 272 and #log == 4)
273 273
274 log = {} 274 log = {}
275 local stat, msg = pcall(foo, true) 275 local stat, msg = pcall(foo, true)
276 assert(msg == 1) 276 assert(msg == 4)
277 assert(log[1] == 4 and log[2] == 3 and log[3] == 2 and log[4] == 2 277 assert(log[1] == 4 and log[2] == 4 and log[3] == 4 and log[4] == 4
278 and #log == 4) 278 and #log == 4)
279 279
280 -- error in toclose in vararg function 280 -- error in toclose in vararg function
@@ -317,7 +317,7 @@ if rawget(_G, "T") then
317 local <toclose> x = setmetatable({}, {__close = function () 317 local <toclose> x = setmetatable({}, {__close = function ()
318 T.alloccount(0); local x = {} -- force a memory error 318 T.alloccount(0); local x = {} -- force a memory error
319 end}) 319 end})
320 error("a") -- common error inside the function's body 320 error(1000) -- common error inside the function's body
321 end 321 end
322 322
323 stack(5) -- ensure a minimal number of CI structures 323 stack(5) -- ensure a minimal number of CI structures
@@ -325,7 +325,7 @@ if rawget(_G, "T") then
325 -- despite memory error, 'y' will be executed and 325 -- despite memory error, 'y' will be executed and
326 -- memory limit will be lifted 326 -- memory limit will be lifted
327 local _, msg = pcall(foo) 327 local _, msg = pcall(foo)
328 assert(msg == "not enough memory") 328 assert(msg == 1000)
329 329
330 local close = func2close(function (self, msg) 330 local close = func2close(function (self, msg)
331 T.alloccount() 331 T.alloccount()
@@ -368,8 +368,7 @@ if rawget(_G, "T") then
368 end 368 end
369 369
370 local _, msg = pcall(test) 370 local _, msg = pcall(test)
371 assert(msg == 1000) 371 assert(msg == "not enough memory") -- reported error is the first one
372
373 372
374 do -- testing 'toclose' in C string buffer 373 do -- testing 'toclose' in C string buffer
375 collectgarbage() 374 collectgarbage()
@@ -453,15 +452,27 @@ end
453 452
454do 453do
455 -- error in a wrapped coroutine raising errors when closing a variable 454 -- error in a wrapped coroutine raising errors when closing a variable
456 local x = false 455 local x = 0
457 local co = coroutine.wrap(function () 456 local co = coroutine.wrap(function ()
458 local <toclose> xv = func2close(function () error("XXX") end) 457 local <toclose> xx = func2close(function () x = x + 1; error("YYY") end)
458 local <toclose> xv = func2close(function () x = x + 1; error("XXX") end)
459 coroutine.yield(100) 459 coroutine.yield(100)
460 error(200) 460 error(200)
461 end) 461 end)
462 assert(co() == 100) 462 assert(co() == 100); assert(x == 0)
463 local st, msg = pcall(co) 463 local st, msg = pcall(co); assert(x == 2)
464 -- should get last error raised 464 assert(not st and msg == 200) -- should get first error raised
465
466 x = 0
467 co = coroutine.wrap(function ()
468 local <toclose> xx = func2close(function () x = x + 1; error("YYY") end)
469 local <toclose> xv = func2close(function () x = x + 1; error("XXX") end)
470 coroutine.yield(100)
471 return 200
472 end)
473 assert(co() == 100); assert(x == 0)
474 local st, msg = pcall(co); assert(x == 2)
475 -- should get first error raised
465 assert(not st and string.find(msg, "%w+%.%w+:%d+: XXX")) 476 assert(not st and string.find(msg, "%w+%.%w+:%d+: XXX"))
466end 477end
467 478