@@ -473,19 +473,25 @@ impl SslError {
473473 /// If attribute setting fails (extremely rare), returns the exception without attributes
474474 pub ( super ) fn create_ssl_error_with_reason (
475475 vm : & VirtualMachine ,
476- library : & str ,
476+ library : Option < & str > ,
477477 reason : & str ,
478478 message : impl Into < String > ,
479479 ) -> PyBaseExceptionRef {
480- let exc = vm. new_exception_msg ( PySSLError :: class ( & vm. ctx ) . to_owned ( ) , message. into ( ) ) ;
480+ let msg = message. into ( ) ;
481+ // SSLError args should be (errno, message) format
482+ // FIXME: Use 1 as generic SSL error code
483+ let exc = vm. new_exception (
484+ PySSLError :: class ( & vm. ctx ) . to_owned ( ) ,
485+ vec ! [ vm. new_pyobj( 1i32 ) , vm. new_pyobj( msg) ] ,
486+ ) ;
481487
482488 // Set library and reason attributes
483489 // Ignore errors as they're extremely rare (e.g., out of memory)
484- let _ = exc . as_object ( ) . set_attr (
485- "library" ,
486- vm. ctx . new_str ( library ) . as_object ( ) . to_owned ( ) ,
487- vm ,
488- ) ;
490+ let library_obj = match library {
491+ Some ( lib ) => vm . ctx . new_str ( lib ) . as_object ( ) . to_owned ( ) ,
492+ None => vm. ctx . none ( ) ,
493+ } ;
494+ let _ = exc . as_object ( ) . set_attr ( "library" , library_obj , vm ) ;
489495 let _ =
490496 exc. as_object ( )
491497 . set_attr ( "reason" , vm. ctx . new_str ( reason) . as_object ( ) . to_owned ( ) , vm) ;
@@ -524,7 +530,12 @@ impl SslError {
524530 . unwrap_or ( "UNKNOWN" ) ;
525531
526532 // Delegate to create_ssl_error_with_reason for actual exception creation
527- Self :: create_ssl_error_with_reason ( vm, lib_str, reason_str, format ! ( "[SSL] {reason_str}" ) )
533+ Self :: create_ssl_error_with_reason (
534+ vm,
535+ Some ( lib_str) ,
536+ reason_str,
537+ format ! ( "[SSL] {reason_str}" ) ,
538+ )
528539 }
529540
530541 /// Convert to Python exception
@@ -533,7 +544,10 @@ impl SslError {
533544 SslError :: WantRead => create_ssl_want_read_error ( vm) ,
534545 SslError :: WantWrite => create_ssl_want_write_error ( vm) ,
535546 SslError :: Timeout ( msg) => timeout_error_msg ( vm, msg) ,
536- SslError :: Syscall ( msg) => vm. new_os_error ( msg) ,
547+ SslError :: Syscall ( msg) => {
548+ // Create SSLError with library=None for syscall errors during SSL operations
549+ Self :: create_ssl_error_with_reason ( vm, None , & msg, msg. clone ( ) )
550+ }
537551 SslError :: Ssl ( msg) => vm. new_exception_msg (
538552 PySSLError :: class ( & vm. ctx ) . to_owned ( ) ,
539553 format ! ( "SSL error: {msg}" ) ,
@@ -1006,7 +1020,13 @@ fn handshake_write_loop(
10061020 // Non-blocking socket would block - return SSLWantWriteError
10071021 return Err ( SslError :: WantWrite ) ;
10081022 }
1009- return Err ( SslError :: Py ( e) ) ;
1023+ // Convert socket error to SSLError during handshake
1024+ let msg = e
1025+ . as_object ( )
1026+ . str ( vm)
1027+ . map ( |s| s. to_string ( ) )
1028+ . unwrap_or_else ( |_| "socket error" . to_string ( ) ) ;
1029+ return Err ( SslError :: Syscall ( msg) ) ;
10101030 }
10111031 }
10121032 } else if written == 0 {
@@ -1072,7 +1092,13 @@ fn handshake_read_data(
10721092 return Ok ( ( false , false ) ) ;
10731093 }
10741094 }
1075- return Err ( SslError :: Py ( e) ) ;
1095+ // Convert socket error to SSLError during handshake
1096+ let msg = e
1097+ . as_object ( )
1098+ . str ( vm)
1099+ . map ( |s| s. to_string ( ) )
1100+ . unwrap_or_else ( |_| "socket error" . to_string ( ) ) ;
1101+ return Err ( SslError :: Syscall ( msg) ) ;
10761102 }
10771103 } ;
10781104
0 commit comments