:do {
/tool e-mail send to=noreply@example.com body="Body Message" subject="Sample subject"
} on-error={ :log error "A friendly message" }
# some other code
If the above code fails due to DNS failure, on-error isn’t triggered. So, I don’t see “A friendly message” in the log. Instead, I see the following…
2025-06-02 07:50:15 dns,error DoH server connection error: while reading - Connection reset by peer
2025-06-02 07:50:15 e-mail,error Error sending e-mail : DNS resolve failed
As a result of this possible bug, the code that follows on-error (“some other code” mentioned in the sample) gets executed.
Update 1: I can reproduce the issue consistently, after removing DNS servers and/or DoH, thus triggering DNS failure (temporarily).
Update 2: I can reproduce the issue with :onerror syntax too.
For now, to avoid email failures (technically DNS/DoH failures), I’ve created the static DNS entries for the email server that is in use.
Anyone else having the same issue (that on-error isn’t triggered for e-mail upon DNS failure)?
A DNS resolution will get caught if you use /tool/fetch or :resolve. Either using do/on-error=, or newer “onerror/in=/do=”.
However /tool/e-mail is “more asynchronous”, so I think, it gets queued like most MTAs… so any error in SMTP protocol happens after the command returns. That’s kinda how it works, so only indication of e-mail error is in the logs.
Now I agree it should “wait” for error in sending, so may be worth filing a feature request or bug. And, I cannot say if older version behave differently, but I want to say this how /tool/e-mail has worked for a while.
Thank you for your insights, Amm0. As suggested, I filed a bug report after consistently able to reproduce the bug (by turning off DNS resolution while testing).
You wrap the email send in a function, that checks DNS name.
Something like this should work in ~v7.17+:
:global sendmail do={
:local emailsplit [:deserialize from=dsv $to delimiter=“@” options=dsv.plain]
:if ([:typeof ($emailsplit->0->1)] = “str”) do={
:onerror errtext in={:resolve ($emailsplit->0->1)} do={
:error “failed: DNS $($emailsplit->0->1) got ‘$errtext’, message ‘$subject’ not sent to $to”
}
} else={
:error “failed: email has invalid format, message ‘$subject’ not sent to $to”
}
/tool/email send to=$to body=$body subject=$subject
}
then you can use the function to send email, with the DNS check…
$sendmail subject=“sub” body=“body” to=“bad”
This will parse the email address to get the domain, and then call :resolve “manually” on domain part - which does error if DNS fails. I then wrap the errors to better log it. The function can be loaded once, and then you can use “$sendmail” as many times as needed.
Yes, they definitely should. And I even asked them in that ticket, but they just replaced some error-catching examples in the docs with the new version.