GUI / lua-resty-mail

A high-level, easy to use, and non-blocking email and SMTP library for OpenResty.
MIT License
66 stars 16 forks source link

Uncaughtable error when host rejects the connection #2

Closed edubart closed 5 years ago

edubart commented 6 years ago

If you try to send an email and hosts rejects the connection with RST, it generates the following error:

2018/08/17 09:24:47 [error] 32027#0: *19 connect() failed (111: Connection refused), context: ngx.timer
2018/08/17 09:24:47 [error] 32027#0: *19 attempt to send data on a closed socket: u:00000000400214C8, c:0000000000000000, ft:0 eof:0, context: ngx.timer

This error is not caughtable even with pcall or handling error status, example:

First on the smtp host we force to reject doing:

iptables -I INPUT -s <myip> -p tcp --dport 587 -j REJECT --reject-with tcp-reset

Then we try to send an email:

local ok, err = pcall(function()
  local mailer = assert(resty_mail.new(config.mailer))
  assert(mailer:send({
    from = 'test@test.com',
    to = 'test@test.com',
    subject = 'test',
    text = 'test',
  }))
end)
print('result', ok, err)

This outputs:

2018/08/17 09:24:47 [error] 32027#0: *19 connect() failed (111: Connection refused), context: ngx.timer
2018/08/17 09:24:47 [error] 32027#0: *19 attempt to send data on a closed socket: u:00000000400214C8, c:0000000000000000, ft:0 eof:0, context: ngx.timer
2018/08/17 09:24:52 [notice] 32027#0: *19 result    false    connect failure: connection refused, context: ngx.timer

What we wanted is just the last message because on the above code we intended to handle all errors.

The problem is even after a connection failure lua-resty-mail try to send data.

GUI commented 5 years ago

@edubart: Apologies for the delay in responding. To clarify, these extra errors are only showing up in the nginx error log, and not actually affecting the behavior or error handling of mailer:send, is that correct? In your example, it looks like mailer:send is returning ok as false and err as connect failure: connection refused (and not throwing any errors in the Lua code), so I believe this is working as expected.

I believe these extra items being logged in your nginx error log are a result of OpenResty's default lua_socket_log_errors behavior:

This directive can be used to toggle error logging when a failure occurs for the TCP or UDP cosockets. If you are already doing proper error handling and logging in your Lua code, then it is recommended to turn this directive off to prevent data flushing in your nginx error log files (which is usually rather expensive).

This setting defaults to on, so this means that any internal socket errors will be logged to the nginx error log, in addition to any error handling or logging you're doing in the Lua code. As noted in the OpenResty docs, you can turn this setting off if you're doing proper error handling (which lua-resty-mail should be doing). However, be aware that this setting operates somewhat globally (at least within the http, server, or location context where you set the lua_socket_log_errors option), so if you have any other Lua code in your server that does socket communication, you should ensure that code also properly handles potential socket errors.

So assuming this issue is related to the lua_socket_log_errors behavior, I think your main options are:

edubart commented 5 years ago

Okay, thanks for the clarification, I guess it's not a bug then, I didn't know that OpenResty logging option.