public static unsafe void ConvertNetworkError(Exception e, C4Error *outError) { var c4err = new C4Error(C4ErrorDomain.LiteCoreDomain, (int)C4ErrorCode.UnexpectedError); var message = default(string); foreach (var inner in FlattenedExceptions(e)) { if (c4err.code != (int)C4ErrorCode.UnexpectedError || c4err.domain != C4ErrorDomain.LiteCoreDomain) { break; } switch (inner) { case CouchbaseException ce: c4err = ce.LiteCoreError; message = ce.Message; break; case SocketException se: switch (se.SocketErrorCode) { case SocketError.HostNotFound: message = se.Message; c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.UnknownHost; break; case SocketError.HostUnreachable: message = se.Message; c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.DNSFailure; break; case SocketError.TimedOut: message = se.Message; c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.Timeout; break; case SocketError.ConnectionAborted: case SocketError.ConnectionReset: case SocketError.Shutdown: message = se.Message; c4err.domain = C4ErrorDomain.POSIXDomain; c4err.code = PosixBase.GetCode(nameof(PosixWindows.ECONNRESET)); break; case SocketError.NetworkUnreachable: message = se.Message; c4err.domain = C4ErrorDomain.POSIXDomain; c4err.code = PosixBase.GetCode(nameof(PosixWindows.ENETRESET)); break; case SocketError.ConnectionRefused: message = se.Message; c4err.domain = C4ErrorDomain.POSIXDomain; c4err.code = PosixBase.GetCode(nameof(PosixWindows.ECONNREFUSED)); break; case SocketError.NetworkDown: message = se.Message; c4err.domain = C4ErrorDomain.POSIXDomain; c4err.code = PosixBase.GetCode(nameof(PosixWindows.ENETDOWN)); break; } break; case IOException ie: if (ie.Message == "The handshake failed due to an unexpected packet format.") { message = ie.Message; c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.TLSHandshakeFailed; } #if __IOS__ if (ie.Message == "Connection closed.") { //AppleTlsContext.cs //case SslStatus.ClosedAbort: // throw new IOException("Connection closed."); message = ie.Message; c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)SocketError.ConnectionAborted; } #endif break; case AuthenticationException ae: if (ae.Message == "The remote certificate is invalid according to the validation procedure.") { message = ae.Message; c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.TLSCertUntrusted; } break; } } if (c4err.code == (int)C4ErrorCode.UnexpectedError && c4err.domain == C4ErrorDomain.LiteCoreDomain) { WriteLog.To.Database.W(Tag, $"No mapping for {e.GetType().Name}; interpreting as 'UnexpectedError'"); if (message == null && e is AggregateException ae) { message = ae.InnerExceptions.Select(x => x.Message).Aggregate((x, y) => $"{x}; {y}"); } } // Use the message of the top-level exception because it will print out nested ones too *outError = Native.c4error_make(c4err.domain, c4err.code, message ?? e.Message); }
public static unsafe void ConvertNetworkError(Exception e, C4Error *outError) { var c4err = new C4Error(C4ErrorDomain.LiteCoreDomain, (int)C4ErrorCode.UnexpectedError); foreach (var inner in FlattenedExceptions(e)) { if (c4err.code != (int)C4ErrorCode.UnexpectedError || c4err.domain != C4ErrorDomain.LiteCoreDomain) { break; } switch (inner) { case CouchbaseException ce: c4err = ce.LiteCoreError; break; case SocketException se: switch (se.SocketErrorCode) { case SocketError.HostNotFound: c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.UnknownHost; break; case SocketError.HostUnreachable: c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.DNSFailure; break; case SocketError.TimedOut: c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.Timeout; break; case SocketError.ConnectionAborted: case SocketError.ConnectionReset: case SocketError.Shutdown: c4err.domain = C4ErrorDomain.POSIXDomain; c4err.code = PosixBase.GetCode(nameof(PosixWindows.ECONNRESET)); break; case SocketError.ConnectionRefused: c4err.domain = C4ErrorDomain.POSIXDomain; c4err.code = PosixBase.GetCode(nameof(PosixWindows.ECONNREFUSED)); break; } break; case IOException ie: if (ie.Message == "The handshake failed due to an unexpected packet format.") { c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.TLSHandshakeFailed; } break; case AuthenticationException ae: if (ae.Message == "The remote certificate is invalid according to the validation procedure.") { c4err.domain = C4ErrorDomain.NetworkDomain; c4err.code = (int)C4NetworkErrorCode.TLSCertUntrusted; } break; } } if (c4err.code == (int)C4ErrorCode.UnexpectedError && c4err.domain == C4ErrorDomain.LiteCoreDomain) { Log.To.Couchbase.W(Tag, $"No mapping for {e.GetType().Name}; interpreting as 'UnexpectedError'"); } // Use the message of the top-level exception because it will print out nested ones too *outError = Native.c4error_make(c4err.domain, c4err.code, e.Message); }