[GSoC PATCH v8 2/2] send-email: finer-grained SMTP error handling
- From
Zheng Yuting <05zyt30@gmail.com>
- Date
- Mar 24, 2025, 14:53 UTC
- Message-ID
- <20250324145332.571813-3-05ZYT30@gmail.com>
- In-Reply-To
- <20250324145332.571813-1-05ZYT30@gmail.com>
Code captured errors but did not process them further. This treated all failures the same without distinguishing SMTP status.
Add handle-smtp_error to extract SMTP status codes using a regex (as defined in RFC 5321) and handle errors as follows:
- No error present: - If a result is provided, return 1 to indicate success. - Otherwise, return 0 to indicate failure.
- Error present with a captured three-digit status code: - For 4yz (transient errors), return 1 and allow retries. - For 5yz (permanent errors), return 0 to indicate failure. - For any other recognized status code, return 1, treating it as a transient error.
- Error present but no status code found: - Return 1 as a transient error.
Signed-off-by: Zheng Yuting <05ZYT30@gmail.com> --- git-send-email.perl | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl index 0f05f55e50..12b1a7c7de 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -1454,14 +1454,42 @@ sub smtp_auth_maybe { $error = $@ || 'Unknown error'; }; - # 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 handle_smtp_error($error, $result); }); return $auth; } +sub handle_smtp_error { + my ($error, $result) = @_; + + # If no error is present, return the result directly + return $result ? 1 : 0 unless $error; + + # Check if an error was captured + # 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;
-- 2.49.0