send-email: capture errors in an eval {} block

Auth relied solely on return values without catching errors. This misjudges
non-credential errors as auth failure without error info.

Patch wraps the entire auth process in an eval {} block to catch
all exceptions, including non-credential errors. It adds a new $error var,
uses 'or do' to prevent flow break, and returns $result ? 1 : 0. And merges
if/else branches, integrates SASL and basic auth, with comments for
future status code handling.

Signed-off-by: Zheng Yuting <05ZYT30@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Zheng Yuting
2025-03-26 15:52:45 +08:00
committed by Junio C Hamano
parent 683c54c999
commit ce20dec4a4

View File

@@ -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,21 +1431,32 @@ 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'});
# NOTE: SMTP status code handling will be added in a subsequent commit,
# return 1 when failed due to non-credential reasons
return $error ? 1 : ($result ? 1 : 0);
});
return $auth;