@@ -1419,7 +1419,7 @@ sub smtp_auth_maybe {
1419
1419
die " invalid smtp auth: '${smtp_auth} '" ;
1420
1420
}
1421
1421
1422
- # TODO: Authentication may fail not because credentials were
1422
+ # Authentication may fail not because credentials were
1423
1423
# invalid but due to other reasons, in which we should not
1424
1424
# reject credentials.
1425
1425
$auth = Git::credential({
@@ -1431,24 +1431,61 @@ sub smtp_auth_maybe {
1431
1431
' password' => $smtp_authpass
1432
1432
}, sub {
1433
1433
my $cred = shift ;
1434
+ my $result ;
1435
+ my $error ;
1436
+
1437
+ # catch all SMTP auth error in a unified eval block
1438
+ eval {
1439
+ if ($smtp_auth ) {
1440
+ my $sasl = Authen::SASL-> new(
1441
+ mechanism => $smtp_auth ,
1442
+ callback => {
1443
+ user => $cred -> {' username' },
1444
+ pass => $cred -> {' password' },
1445
+ authname => $cred -> {' username' },
1446
+ }
1447
+ );
1448
+ $result = $smtp -> auth($sasl );
1449
+ } else {
1450
+ $result = $smtp -> auth($cred -> {' username' }, $cred -> {' password' });
1451
+ }
1452
+ 1; # ensure true value is returned if no exception is thrown
1453
+ } or do {
1454
+ $error = $@ || ' Unknown error' ;
1455
+ };
1456
+
1457
+ return ($error
1458
+ ? handle_smtp_error($error )
1459
+ : ($result ? 1 : 0));
1460
+ });
1434
1461
1435
- if ($smtp_auth ) {
1436
- my $sasl = Authen::SASL-> new(
1437
- mechanism => $smtp_auth ,
1438
- callback => {
1439
- user => $cred -> {' username' },
1440
- pass => $cred -> {' password' },
1441
- authname => $cred -> {' username' },
1442
- }
1443
- );
1462
+ return $auth ;
1463
+ }
1444
1464
1445
- return !!$smtp -> auth($sasl );
1465
+ sub handle_smtp_error {
1466
+ my ($error ) = @_ ;
1467
+
1468
+ # Parse SMTP status code from error message in:
1469
+ # https://www.rfc-editor.org/rfc/rfc5321.html
1470
+ if ($error =~ / \b (\d {3})\b / ) {
1471
+ my $status_code = $1 ;
1472
+ if ($status_code =~ / ^4/ ) {
1473
+ # 4yz: Transient Negative Completion reply
1474
+ warn " SMTP transient error (status code $status_code ): $error " ;
1475
+ return 1;
1476
+ } elsif ($status_code =~ / ^5/ ) {
1477
+ # 5yz: Permanent Negative Completion reply
1478
+ warn " SMTP permanent error (status code $status_code ): $error " ;
1479
+ return 0;
1446
1480
}
1481
+ # If no recognized status code is found, treat as transient error
1482
+ warn " SMTP unknown error: $error . Treating as transient failure." ;
1483
+ return 1;
1484
+ }
1447
1485
1448
- return !!$smtp -> auth($cred -> {' username' }, $cred -> {' password' });
1449
- });
1450
-
1451
- return $auth ;
1486
+ # If no status code is found, treat as transient error
1487
+ warn " SMTP generic error: $error " ;
1488
+ return 1;
1452
1489
}
1453
1490
1454
1491
sub ssl_verify_params {
0 commit comments