Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime errors are not reported in chained promises #4

Open
joagre opened this issue Nov 2, 2016 · 2 comments
Open

Runtime errors are not reported in chained promises #4

joagre opened this issue Nov 2, 2016 · 2 comments

Comments

@joagre
Copy link

joagre commented Nov 2, 2016

If I make a programming error in the first promise (in a promise chain) I get an expected runtime error but if I make a programming error in the second promise I get no runtime error.

I slightly modifed your chained promises example to verify this:

local deferred = require "lib.deferred"

function readasync(filename, cb)
  if filename == 'first.txt' then
    call_missing_function()
    cb("content1", nil)
  else
    --call_missing_function()
    cb("content2", nil)
  end
end

function read(filename)
  local d = deferred.new()
  readasync(filename, function(contents, err)
    if err == nil then
      d:resolve(contents)
    else
      d:reject(err)
    end
  end)
  return d
end

read('first.txt'):next(function(s)
  print('First file:', s)
  return read('second.txt')
end):next(function(s)
  print('Second file:', s)
end):next(nil, function(err)
  -- error while reading first or second file
  print('Error:', err)
end)

When I run the above I get an expected runtime error:

nov. 02 06:38:45.241 ERROR: Runtime error
  /Users/jocke/src/blackmode/trunk/app/ui2/main.lua:5: attempt to call global 'call_missing_function' (a nil value)
  stack traceback:
  /Users/jocke/src/blackmode/trunk/app/ui2/main.lua:5: in function 'readasync'
  /Users/jocke/src/blackmode/trunk/app/ui2/main.lua:15: in function 'read'
  /Users/jocke/src/blackmode/trunk/app/ui2/main.lua:25: in main chunk

If I change the readsync function above to this:

function readasync(filename, cb)
  if filename == 'first.txt' then
    --call_missing_function()
    cb("content1", nil)
  else
    call_missing_function()
    cb("content2", nil)
  end
end

Then I just get the custom error message and no run-time error:

Error:	/Users/jocke/src/blackmode/trunk/app/ui2/main.lua:8: attempt to call global 'call_missing_function' (a nil value)

I this to be expected?

Kind regards

@joagre
Copy link
Author

joagre commented Nov 15, 2016

I ended up removing all the pcalls i deferred.lua. Works like a charm.

@zserge
Copy link
Owner

zserge commented Jan 1, 2017

Sorry for a late reply.

You're right, this may be confusing. According to the A+ spec:

If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.

That's why throwing no runtime errors and passing them to error callback is the expected behavior. The catch is that you first function is called like a normal function and thus there is no outer handler to catch the runtime error.

I've just pushed a tiny change to the library. Now deferred.new() may (and should) receive a function that deals with the deferred object. There is no need to create deferred object manually anymore. With this modification your example should be rewritten like this:

local deferred = require "deferred"

function readasync(filename, cb)
  if filename == 'first.txt' then
    call_missing_function()
    cb("content1", nil)
  else
    --call_missing_function()
    cb("content2", nil)
  end
end

function read(filename)
	return function(d)
		readasync(filename, function(contents, err)
			if err == nil then
				d:resolve(contents)
			else
				d:reject(err)
			end
		end)
	end
end

deferred.new(read('first.txt')):next(function(s)
  print('First file:', s)
  return read('second.txt')
end):next(function(s)
  print('Second file:', s)
end):next(nil, function(err)
  -- error while reading first or second file
  print('Error:', err)
end)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants