@@ -607,7 +607,7 @@ impl IntoRequest<UpgradingWebsocket> for WebSocketOptions {
607607 . map ( String :: as_str)
608608 . collect :: < Vec < _ > > ( ) ,
609609 )
610- . unwrap ( ) ;
610+ . map_err ( |error| RequestError :: Connect ( error . to_string ( ) ) ) ? ;
611611
612612 return Ok ( UpgradingWebsocket {
613613 protocol : Some ( socket. protocol ( ) ) ,
@@ -619,14 +619,11 @@ impl IntoRequest<UpgradingWebsocket> for WebSocketOptions {
619619
620620 #[ cfg( not( target_arch = "wasm32" ) ) ]
621621 {
622- let response = native:: send_request ( request, & self . protocols )
623- . await
624- . unwrap ( ) ;
622+ let response = native:: send_request ( request, & self . protocols ) . await ?;
625623
626624 let ( inner, protocol) = response
627625 . into_stream_and_protocol ( self . protocols , None )
628- . await
629- . unwrap ( ) ;
626+ . await ?;
630627
631628 return Ok ( UpgradingWebsocket {
632629 protocol,
@@ -1139,6 +1136,7 @@ mod native {
11391136 use crate :: ClientRequest ;
11401137
11411138 use super :: { CloseCode , Message , WebsocketError } ;
1139+ use dioxus_fullstack_core:: RequestError ;
11421140 use reqwest:: {
11431141 header:: { HeaderName , HeaderValue } ,
11441142 Response , StatusCode , Version ,
@@ -1466,4 +1464,104 @@ mod native {
14661464 u16:: from ( value) . into ( )
14671465 }
14681466 }
1467+
1468+ impl From < HandshakeError > for RequestError {
1469+ fn from ( value : HandshakeError ) -> Self {
1470+ let string = value. to_string ( ) ;
1471+ match value {
1472+ HandshakeError :: UnexpectedStatusCode ( status) => {
1473+ Self :: Status ( string, status. as_u16 ( ) )
1474+ }
1475+ HandshakeError :: UnsupportedHttpVersion ( _)
1476+ | HandshakeError :: MissingHeader { .. }
1477+ | HandshakeError :: UnexpectedHeaderValue { .. }
1478+ | HandshakeError :: ExpectedAProtocol
1479+ | HandshakeError :: UnexpectedProtocol { .. }
1480+ | HandshakeError :: ServerRespondedWithDifferentVersion => Self :: Connect ( string) ,
1481+ }
1482+ }
1483+ }
1484+
1485+ trait IntoRequestError {
1486+ fn into_request_error ( self ) -> RequestError ;
1487+ }
1488+
1489+ impl IntoRequestError for reqwest:: Error {
1490+ fn into_request_error ( self ) -> RequestError {
1491+ const DEFAULT_STATUS_CODE : u16 = 0 ;
1492+ let string = self . to_string ( ) ;
1493+ if self . is_builder ( ) {
1494+ RequestError :: Builder ( string)
1495+ } else if self . is_redirect ( ) {
1496+ RequestError :: Redirect ( string)
1497+ } else if self . is_status ( ) {
1498+ RequestError :: Status (
1499+ string,
1500+ self . status ( )
1501+ . as_ref ( )
1502+ . map ( StatusCode :: as_u16)
1503+ . unwrap_or ( DEFAULT_STATUS_CODE ) ,
1504+ )
1505+ } else if self . is_body ( ) {
1506+ RequestError :: Body ( string)
1507+ } else if self . is_decode ( ) {
1508+ RequestError :: Decode ( string)
1509+ } else if self . is_upgrade ( ) {
1510+ RequestError :: Connect ( string)
1511+ } else {
1512+ RequestError :: Request ( string)
1513+ }
1514+ }
1515+ }
1516+
1517+ impl IntoRequestError for tungstenite:: Error {
1518+ fn into_request_error ( self ) -> RequestError {
1519+ match self {
1520+ tungstenite:: Error :: ConnectionClosed => {
1521+ RequestError :: Connect ( "websocket connection closed" . to_owned ( ) )
1522+ }
1523+ tungstenite:: Error :: AlreadyClosed => {
1524+ RequestError :: Connect ( "websocket already closed" . to_owned ( ) )
1525+ }
1526+ tungstenite:: Error :: Io ( error) => RequestError :: Connect ( error. to_string ( ) ) ,
1527+ tungstenite:: Error :: Tls ( error) => RequestError :: Connect ( error. to_string ( ) ) ,
1528+ tungstenite:: Error :: Capacity ( error) => RequestError :: Body ( error. to_string ( ) ) ,
1529+ tungstenite:: Error :: Protocol ( error) => RequestError :: Request ( error. to_string ( ) ) ,
1530+ tungstenite:: Error :: WriteBufferFull ( message) => {
1531+ RequestError :: Body ( message. to_string ( ) )
1532+ }
1533+ tungstenite:: Error :: Utf8 ( error) => RequestError :: Decode ( error) ,
1534+ tungstenite:: Error :: AttackAttempt => {
1535+ RequestError :: Request ( "Tungstenite attack attempt detected" . to_owned ( ) )
1536+ }
1537+ tungstenite:: Error :: Url ( error) => RequestError :: Builder ( error. to_string ( ) ) ,
1538+ tungstenite:: Error :: Http ( response) => {
1539+ let status_code = response. status ( ) ;
1540+ RequestError :: Status ( format ! ( "HTTP error: {status_code}" ) , status_code. as_u16 ( ) )
1541+ }
1542+ tungstenite:: Error :: HttpFormat ( error) => RequestError :: Builder ( error. to_string ( ) ) ,
1543+ }
1544+ }
1545+ }
1546+
1547+ impl From < WebsocketError > for RequestError {
1548+ fn from ( value : WebsocketError ) -> Self {
1549+ match value {
1550+ WebsocketError :: ConnectionClosed { code, description } => {
1551+ Self :: Connect ( format ! ( "connection closed ({code}): {description}" ) )
1552+ }
1553+ WebsocketError :: AlreadyClosed => Self :: Connect ( value. to_string ( ) ) ,
1554+ WebsocketError :: Capacity => Self :: Body ( value. to_string ( ) ) ,
1555+ WebsocketError :: Unexpected => Self :: Request ( value. to_string ( ) ) ,
1556+ WebsocketError :: Uninitialized => Self :: Builder ( value. to_string ( ) ) ,
1557+ WebsocketError :: Handshake ( error) => error. into ( ) ,
1558+ WebsocketError :: Reqwest ( error) => error. into_request_error ( ) ,
1559+ WebsocketError :: Tungstenite ( error) => error. into_request_error ( ) ,
1560+ WebsocketError :: Serialization ( error) => Self :: Serialization ( error. to_string ( ) ) ,
1561+ WebsocketError :: Deserialization ( error) => Self :: Decode ( error. to_string ( ) ) ,
1562+ WebsocketError :: Json ( error) => Self :: Decode ( error. to_string ( ) ) ,
1563+ WebsocketError :: Cbor ( error) => Self :: Decode ( error. to_string ( ) ) ,
1564+ }
1565+ }
1566+ }
14691567}
0 commit comments