Subject: [GSoC PATCH v4 1/2] Unify capture of SMTP errors

From: Zheng Yuting <[email-masked]>
Date: Sun, 16 Mar 2025 13:09:19 +0800

This change adds local variables $result and $error to store authentication
return results and exception information respectively.

In the eval block, different auth methods are called depending on whether
the SMTP authentication mechanism is specified, and true is returned when
there is no exception.

After catching the exception, the error information is saved. This makes
the error capture logic more centralized and easier to understand, and
lays the foundation for subsequent expansion.

Signed-off-by: Zheng Yuting <[email-masked]>
---
 git-send-email.perl | 45 ++++++++++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/git-send-email.perl b/git-send-email.perl
index 798d59b84f..8feb43e9f7 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -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,25 +1431,32 @@ sub smtp_auth_maybe {
 		'password' => $smtp_authpass
 	}, sub {
 		my $cred = shift;
+		my $result;
+		my $error;
+
+		# 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';
+		};

-		if ($smtp_auth) {
-			my $sasl = Authen::SASL->new(
-				mechanism => $smtp_auth,
-				callback => {
-					user => $cred->{'username'},
-					pass => $cred->{'password'},
-					authname => $cred->{'username'},
-				}
-			);
-
-			return !!$smtp->auth($sasl);
-		}
-
-		return !!$smtp->auth($cred->{'username'}, $cred->{'password'});
-	});
-
-	return $auth;
-}
+		# NOTE: SMTP status code handling will be added in a subsequent commit
+		return $result ? 1 : 0;
+	}

 sub ssl_verify_params {
 	eval {
--
2.48.1