Merge branch 'zy/send-email-error-handling'
Auth-related (and unrelated) error handling in send-email has been
made more robust.
* zy/send-email-error-handling:
send-email: finer-grained SMTP error handling
send-email: capture errors in an eval {} block
maint
commit
4c58159add
|
|
@ -1419,7 +1419,7 @@ sub smtp_auth_maybe {
|
|||
die "invalid smtp auth: '${smtp_auth}'";
|
||||
}
|
||||
|
||||
# TODO: Authentication may fail not because credentials were
|
||||
# Authentication may fail not because credentials were
|
||||
# invalid but due to other reasons, in which we should not
|
||||
# reject credentials.
|
||||
$auth = Git::credential({
|
||||
|
|
@ -1431,26 +1431,63 @@ sub smtp_auth_maybe {
|
|||
'password' => $smtp_authpass
|
||||
}, sub {
|
||||
my $cred = shift;
|
||||
my $result;
|
||||
my $error;
|
||||
|
||||
if ($smtp_auth) {
|
||||
my $sasl = Authen::SASL->new(
|
||||
mechanism => $smtp_auth,
|
||||
callback => {
|
||||
user => $cred->{'username'},
|
||||
pass => $cred->{'password'},
|
||||
authname => $cred->{'username'},
|
||||
}
|
||||
);
|
||||
# catch all SMTP auth error in a unified eval block
|
||||
eval {
|
||||
if ($smtp_auth) {
|
||||
my $sasl = Authen::SASL->new(
|
||||
mechanism => $smtp_auth,
|
||||
callback => {
|
||||
user => $cred->{'username'},
|
||||
pass => $cred->{'password'},
|
||||
authname => $cred->{'username'},
|
||||
}
|
||||
);
|
||||
$result = $smtp->auth($sasl);
|
||||
} else {
|
||||
$result = $smtp->auth($cred->{'username'}, $cred->{'password'});
|
||||
}
|
||||
1; # ensure true value is returned if no exception is thrown
|
||||
} or do {
|
||||
$error = $@ || 'Unknown error';
|
||||
};
|
||||
|
||||
return !!$smtp->auth($sasl);
|
||||
}
|
||||
|
||||
return !!$smtp->auth($cred->{'username'}, $cred->{'password'});
|
||||
return ($error
|
||||
? handle_smtp_error($error)
|
||||
: ($result ? 1 : 0));
|
||||
});
|
||||
|
||||
return $auth;
|
||||
}
|
||||
|
||||
sub handle_smtp_error {
|
||||
my ($error) = @_;
|
||||
|
||||
# Parse SMTP status code from error message in:
|
||||
# https://www.rfc-editor.org/rfc/rfc5321.html
|
||||
if ($error =~ /\b(\d{3})\b/) {
|
||||
my $status_code = $1;
|
||||
if ($status_code =~ /^4/) {
|
||||
# 4yz: Transient Negative Completion reply
|
||||
warn "SMTP transient error (status code $status_code): $error";
|
||||
return 1;
|
||||
} elsif ($status_code =~ /^5/) {
|
||||
# 5yz: Permanent Negative Completion reply
|
||||
warn "SMTP permanent error (status code $status_code): $error";
|
||||
return 0;
|
||||
}
|
||||
# If no recognized status code is found, treat as transient error
|
||||
warn "SMTP unknown error: $error. Treating as transient failure.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
# If no status code is found, treat as transient error
|
||||
warn "SMTP generic error: $error";
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub ssl_verify_params {
|
||||
eval {
|
||||
require IO::Socket::SSL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue