diff --git a/cpp/src/slice2swift/Gen.cpp b/cpp/src/slice2swift/Gen.cpp index 14d5e8f06b2..6b50948c472 100644 --- a/cpp/src/slice2swift/Gen.cpp +++ b/cpp/src/slice2swift/Gen.cpp @@ -1013,7 +1013,7 @@ Gen::TypesVisitor::visitEnum(const EnumPtr& p) out << nl << "let rawValue: " << enumType << " = try read(enumMaxValue: " << p->maxValue() << ")"; out << nl << "guard let val = " << name << "(rawValue: rawValue) else"; out << sb; - out << nl << "throw " << getUnqualified("Ice.MarshalException", swiftModule) << "(reason: \"invalid enum value\")"; + out << nl << "throw " << getUnqualified("Ice.MarshalException", swiftModule) << "(\"invalid enum value\")"; out << eb; out << nl << "return val"; out << eb; diff --git a/swift/src/Ice/CommunicatorI.swift b/swift/src/Ice/CommunicatorI.swift index 1d7b966dbb1..bf287edf20f 100644 --- a/swift/src/Ice/CommunicatorI.swift +++ b/swift/src/Ice/CommunicatorI.swift @@ -254,7 +254,7 @@ class CommunicatorI: LocalObject, Communicator { func makeProxyImpl(_ proxyString: String) throws -> ProxyImpl where ProxyImpl: ObjectPrxI { guard let proxy: ProxyImpl = try stringToProxyImpl(proxyString) else { - throw ParseException(str: "invalid empty proxy string") + throw ParseException("invalid empty proxy string") } return proxy } diff --git a/swift/src/Ice/Connection.swift b/swift/src/Ice/Connection.swift index 1eafc91166a..827d42abffd 100644 --- a/swift/src/Ice/Connection.swift +++ b/swift/src/Ice/Connection.swift @@ -24,7 +24,7 @@ extension InputStream { public func read() throws -> CompressBatch { let rawValue: UInt8 = try read(enumMaxValue: 2) guard let val = CompressBatch(rawValue: rawValue) else { - throw MarshalException(reason: "invalid enum value") + throw MarshalException("invalid enum value") } return val } @@ -87,7 +87,7 @@ extension InputStream { public func read() throws -> ConnectionClose { let rawValue: UInt8 = try read(enumMaxValue: 2) guard let val = ConnectionClose(rawValue: rawValue) else { - throw MarshalException(reason: "invalid enum value") + throw MarshalException("invalid enum value") } return val } diff --git a/swift/src/Ice/CurrentExtensions.swift b/swift/src/Ice/CurrentExtensions.swift index 588c3e844b5..c9b35f958ec 100644 --- a/swift/src/Ice/CurrentExtensions.swift +++ b/swift/src/Ice/CurrentExtensions.swift @@ -79,30 +79,33 @@ extension Current { fatalError("Unexpected RequestFailedException subclass") } - if rfe.id.name.isEmpty { - rfe.id = id - } + var id = rfe.id + var facet = rfe.facet + var operation = rfe.operation - if rfe.facet.isEmpty { - rfe.facet = facet + if id.name.isEmpty { + id = self.id + facet = self.facet } - if rfe.operation.isEmpty { - rfe.operation = operation + if operation.isEmpty { + operation = self.operation } - // We must call ice_print _after_ setting the properties above. - exceptionMessage = rfe.ice_print() + // [7..] to slice-off the "::Ice::" prefix + let typeName = String(exceptionId!.dropFirst(7)) + exceptionMessage = RequestFailedException.makeMessage( + typeName: typeName, id: id, facet: facet, operation: operation) if requestId != 0 { ostr.write(replyStatus.rawValue) - ostr.write(rfe.id) - if rfe.facet.isEmpty { + ostr.write(id) + if facet.isEmpty { ostr.write(size: 0) } else { - ostr.write([rfe.facet]) + ostr.write([facet]) } - ostr.write(rfe.operation) + ostr.write(operation) } case let ex as UserException: @@ -120,28 +123,23 @@ extension Current { case let ex as UnknownLocalException: exceptionId = ex.ice_id() replyStatus = .unknownLocalException - exceptionMessage = ex.unknown + exceptionMessage = ex.message case let ex as UnknownUserException: exceptionId = ex.ice_id() replyStatus = .unknownUserException - exceptionMessage = ex.unknown + exceptionMessage = ex.message case let ex as UnknownException: exceptionId = ex.ice_id() replyStatus = .unknownException - exceptionMessage = ex.unknown + exceptionMessage = ex.message case let ex as LocalException: exceptionId = ex.ice_id() replyStatus = .unknownLocalException exceptionMessage = "\(ex)" - case let ex as Exception: - exceptionId = ex.ice_id() - replyStatus = .unknownException - exceptionMessage = "\(ex)" - default: replyStatus = .unknownException exceptionId = "\(type(of: error))" diff --git a/swift/src/Ice/EndpointSelectionType.swift b/swift/src/Ice/EndpointSelectionType.swift index e0f224fadb7..5ffc8f22717 100644 --- a/swift/src/Ice/EndpointSelectionType.swift +++ b/swift/src/Ice/EndpointSelectionType.swift @@ -21,7 +21,7 @@ extension InputStream { public func read() throws -> EndpointSelectionType { let rawValue: UInt8 = try read(enumMaxValue: 1) guard let val = EndpointSelectionType(rawValue: rawValue) else { - throw MarshalException(reason: "invalid enum value") + throw MarshalException("invalid enum value") } return val } diff --git a/swift/src/Ice/Exception.swift b/swift/src/Ice/Exception.swift index 80e791dfee9..4ac31c76732 100644 --- a/swift/src/Ice/Exception.swift +++ b/swift/src/Ice/Exception.swift @@ -1,90 +1,4 @@ // Copyright (c) ZeroC, Inc. /// Base protocol for Ice exceptions. -public protocol Exception: Error { - /// Returns the type id of this exception. - /// - /// - returns: `String` - The type id of this exception. - func ice_id() -> String - static func ice_staticId() -> String -} - -extension Exception { - public func ice_id() -> String { - return type(of: self).ice_staticId() - } -} - -/// Base class for Ice run-time exceptions. -open class LocalException: Exception, CustomStringConvertible { - public let file: String - public let line: Int32 - - public var description: String { - return "\(file): \(line): \(ice_id())\(ice_print())" - } - - public init(file: String = #file, line: Int32 = #line) { - self.file = file - self.line = line - } - - open class func ice_staticId() -> String { - return "::Ice::LocalException" - } - - /// Returns a stringified description of this exception. - /// - /// - returns: `String` - The exception description. - open func ice_print() -> String { - return "" - } -} - -/// Base class for Ice user exceptions. -open class UserException: Exception { - public required init() {} - - open func _iceReadImpl(from _: InputStream) throws {} - open func _iceWriteImpl(to _: OutputStream) {} - - open func _usesClasses() -> Bool { - return false - } - - /// Returns the Slice type ID of the exception. - /// - /// - returns: `String` The Slice type ID. - open class func ice_staticId() -> String { - return "::Ice::UserException" - } - - open func _iceRead(from istr: InputStream) throws { - istr.startException() - try _iceReadImpl(from: istr) - try istr.endException() - } - - open func _iceWrite(to ostr: OutputStream) { - ostr.startException() - _iceWriteImpl(to: ostr) - ostr.endException() - } -} - -/// Error used to wrap C++ std::exception errors. -public class RuntimeError: LocalException { - private let message: String - - override public var description: String { - return message - } - - override open class func ice_staticId() -> String { - return "::Ice::RuntimeError" - } - - public init(_ message: String) { - self.message = message - } -} +public protocol Exception: Error {} diff --git a/swift/src/Ice/Initialize.swift b/swift/src/Ice/Initialize.swift index e113281f875..c18b3d568a6 100644 --- a/swift/src/Ice/Initialize.swift +++ b/swift/src/Ice/Initialize.swift @@ -12,7 +12,7 @@ import IceImpl // let factoriesRegistered: Bool = { ICEUtil.registerFactories( - exception: ExceptionFactory.self, + exception: LocalExceptionFactory.self, connectionInfo: ConnectionInfoFactory.self, endpointInfo: EndpointInfoFactory.self, adminFacet: AdminFacetFactory.self) diff --git a/swift/src/Ice/InputStream.swift b/swift/src/Ice/InputStream.swift index 52186eafacd..d8c01b260e1 100644 --- a/swift/src/Ice/InputStream.swift +++ b/swift/src/Ice/InputStream.swift @@ -55,11 +55,11 @@ public class InputStream { public func readEncapsulation() throws -> (bytes: Data, encoding: EncodingVersion) { let sz: Int32 = try read() if sz < 6 { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } if sz - 4 > remaining { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } let encoding: EncodingVersion = try read() @@ -87,10 +87,10 @@ public class InputStream { let sz: Int32 = try read() if sz < 6 { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } if sz - 4 > remaining { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } let encoding: EncodingVersion = try read() @@ -107,13 +107,11 @@ public class InputStream { if !encaps.encoding_1_0 { try skipOptionals() if pos != encaps.start + encaps.sz { - throw MarshalException( - reason: "buffer size does not match decoded encapsulation size") + throw MarshalException("buffer size does not match decoded encapsulation size") } } else if pos != encaps.start + encaps.sz { if pos + 1 != encaps.start + encaps.sz { - throw MarshalException( - reason: "buffer size does not match decoded encapsulation size") + throw MarshalException("buffer size does not match decoded encapsulation size") } // @@ -134,11 +132,11 @@ public class InputStream { let sz: Int32 = try read() if sz < 6 { - throw MarshalException(reason: "invalid encapsulation size") + throw MarshalException("invalid encapsulation size") } if sz - 4 > remaining { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } let encoding: EncodingVersion = try read() @@ -146,7 +144,7 @@ public class InputStream { if encoding == Encoding_1_0 { if sz != 6 { - throw MarshalException(reason: "invalid encapsulation size") + throw MarshalException("invalid encapsulation size") } } else { // @@ -166,7 +164,7 @@ public class InputStream { let sz: Int32 = try read() if sz < 6 { - throw MarshalException(reason: "invalid encapsulation size") + throw MarshalException("invalid encapsulation size") } let encodingVersion: EncodingVersion = try read() @@ -239,7 +237,7 @@ public class InputStream { case .FSize: try skip(read()) case .Class: - throw MarshalException(reason: "cannot skip an optional class") + throw MarshalException("cannot skip an optional class") } } @@ -280,7 +278,7 @@ public class InputStream { precondition(pos + offset >= 0, "Negative position") guard offset <= remaining else { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } pos += offset } @@ -378,12 +376,11 @@ public class InputStream { // if let usv = v as? UnknownSlicedValue { throw MarshalException( - reason: "cannot find value factory to unmarshal class with type ID '\(usv.ice_id())'") + "cannot find value factory to unmarshal class with type ID '\(usv.ice_id())'") } throw MarshalException( - reason: - "failed to unmarshal class with type ID '\(expectedType.ice_staticId())': value factory returned a class with type ID '\(v.ice_id())'" + "failed to unmarshal class with type ID '\(expectedType.ice_staticId())': value factory returned a class with type ID '\(v.ice_id())'" ) } } @@ -395,7 +392,7 @@ extension InputStream { public func read() throws -> Element where Element: StreamableNumeric { let size = MemoryLayout.size guard size <= remaining else { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } var value: Element = 0 @@ -469,7 +466,7 @@ extension InputStream { /// - returns: `UInt8` - The byte read from the stream. public func read() throws -> UInt8 { guard remaining > 0 else { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } let value = data[pos] pos += 1 @@ -616,7 +613,7 @@ extension InputStream { // data: it's claiming having more data that what is possible to read. // if startSeq + minSeqSize > data.count { - throw MarshalException(reason: endOfBufferMessage) + throw MarshalException(endOfBufferMessage) } return sz @@ -651,7 +648,7 @@ extension InputStream { // First 3 bits. guard let format = OptionalFormat(rawValue: v & 0x07) else { - throw MarshalException(reason: "invalid optional format") + throw MarshalException("invalid optional format") } var tag = Int32(v >> 3) if tag == 30 { @@ -666,7 +663,7 @@ extension InputStream { try skipOptional(format: format) // Skip optional data members } else { if format != expectedFormat { - throw MarshalException(reason: "invalid optional data member `\(tag)': unexpected format") + throw MarshalException("invalid optional data member `\(tag)': unexpected format") } return true } @@ -685,20 +682,20 @@ extension InputStream { } else if enumMaxValue < 32767 { let v: Int16 = try read() guard v <= UInt8.max else { - throw MarshalException(reason: "unexpected enumerator value") + throw MarshalException("unexpected enumerator value") } return UInt8(v) } else { let v: Int32 = try read() guard v <= UInt8.max else { - throw MarshalException(reason: "unexpected enumerator value") + throw MarshalException("unexpected enumerator value") } return UInt8(v) } } else { let v = try readSize() guard v <= UInt8.max else { - throw MarshalException(reason: "unexpected enumerator value") + throw MarshalException("unexpected enumerator value") } return UInt8(v) } @@ -735,7 +732,7 @@ extension InputStream { try skip(size) let end = pos guard let str = String(data: data[start.. 0 { - throw MarshalException(reason: "invalid object id") + throw MarshalException("invalid object id") } index = -index @@ -1168,7 +1165,7 @@ private class EncapsDecoder10: EncapsDecoder { // next type ID, which raises MarshalException when the // input buffer underflows. - throw MarshalException(reason: "unknown exception type '\(mostDerivedId)'") + throw MarshalException("unknown exception type '\(mostDerivedId)'") } } } @@ -1186,7 +1183,7 @@ private class EncapsDecoder10: EncapsDecoder { try startSlice() let sz = try stream.readSize() // For compatibility with the old AFM. if sz != 0 { - throw MarshalException(reason: "invalid Object slice") + throw MarshalException("invalid Object slice") } try endSlice() } @@ -1221,7 +1218,7 @@ private class EncapsDecoder10: EncapsDecoder { sliceSize = try stream.read() if sliceSize < 4 { - throw MarshalException(reason: "unexpected slice size") + throw MarshalException("unexpected slice size") } return typeId } @@ -1247,7 +1244,7 @@ private class EncapsDecoder10: EncapsDecoder { // If any entries remain in the patch map, the sender has sent an index for an object, but failed // to supply the object. // - throw MarshalException(reason: "index for class received, but no instance") + throw MarshalException("index for class received, but no instance") } } @@ -1255,7 +1252,7 @@ private class EncapsDecoder10: EncapsDecoder { let index: Int32 = try stream.read() if index <= 0 { - throw MarshalException(reason: "invalid object id") + throw MarshalException("invalid object id") } sliceType = SliceType.ValueSlice @@ -1274,7 +1271,7 @@ private class EncapsDecoder10: EncapsDecoder { // marks the last slice. // if typeId == "::Ice::Object" { - throw MarshalException(reason: "cannot find value factory for type ID '\(mostDerivedId)'") + throw MarshalException("cannot find value factory for type ID '\(mostDerivedId)'") } v = try newInstance(typeId: typeId) @@ -1305,7 +1302,7 @@ private class EncapsDecoder10: EncapsDecoder { } classGraphDepth += 1 if classGraphDepth > classGraphDepthMax { - throw MarshalException(reason: "maximum class graph depth reached") + throw MarshalException("maximum class graph depth reached") } // @@ -1378,7 +1375,7 @@ private class EncapsDecoder11: EncapsDecoder { func readValue(cb: @escaping Callback) throws { let index = try stream.readSize() if index < 0 { - throw MarshalException(reason: "invalid object id") + throw MarshalException("invalid object id") } else if index == 0 { try cb(nil) } else if current != nil, current.sliceFlags.contains(.FLAG_HAS_INDIRECTION_TABLE) { @@ -1438,10 +1435,11 @@ private class EncapsDecoder11: EncapsDecoder { try skipSlice() if current.sliceFlags.contains(.FLAG_IS_LAST_SLICE) { + // TODO: the correct exception is MarshalException!! if let range = mostDerivedId.range(of: "::") { - throw UnknownUserException(unknown: String(mostDerivedId[range.upperBound...])) + throw UnknownUserException(badTypeId: String(mostDerivedId[range.upperBound...])) } else { - throw UnknownUserException(unknown: mostDerivedId) + throw UnknownUserException(badTypeId: mostDerivedId) } } @@ -1512,7 +1510,7 @@ private class EncapsDecoder11: EncapsDecoder { if current.sliceFlags.contains(SliceFlags.FLAG_HAS_SLICE_SIZE) { current.sliceSize = try stream.read() if current.sliceSize < 4 { - throw MarshalException(reason: "invalid slice size") + throw MarshalException("invalid slice size") } } else { current.sliceSize = 0 @@ -1544,12 +1542,12 @@ private class EncapsDecoder11: EncapsDecoder { // unknown optional data members. // if indirectionTable.isEmpty { - throw MarshalException(reason: "empty indirection table") + throw MarshalException("empty indirection table") } if current.indirectPatchList.isEmpty, !current.sliceFlags.contains(.FLAG_HAS_OPTIONAL_MEMBERS) { - throw MarshalException(reason: "no references to indirection table") + throw MarshalException("no references to indirection table") } // @@ -1558,7 +1556,7 @@ private class EncapsDecoder11: EncapsDecoder { for e in current.indirectPatchList { precondition(e.index >= 0) if e.index >= indirectionTable.count { - throw MarshalException(reason: "indirection out of range") + throw MarshalException("indirection out of range") } try addPatchEntry(index: indirectionTable[Int(e.index)], cb: e.cb) } @@ -1577,12 +1575,11 @@ private class EncapsDecoder11: EncapsDecoder { } else { if current.sliceType == .ValueSlice { throw MarshalException( - reason: - "cannot find value factory for type ID '\(current.typeId!)' and compact format prevents slicing" + "cannot find value factory for type ID '\(current.typeId!)' and compact format prevents slicing" ) } else { throw MarshalException( - reason: "cannot find user exception for type ID '\(current.typeId!)'") + "cannot find user exception for type ID '\(current.typeId!)'") } } @@ -1741,7 +1738,7 @@ private class EncapsDecoder11: EncapsDecoder { classGraphDepth += 1 if classGraphDepth > classGraphDepthMax { - throw MarshalException(reason: "maximum class graph depth reached") + throw MarshalException("maximum class graph depth reached") } // @@ -1756,7 +1753,7 @@ private class EncapsDecoder11: EncapsDecoder { // If any entries remain in the patch map, the sender has sent an index for an instance, but failed // to supply the instance. // - throw MarshalException(reason: "index for class received, but no instance") + throw MarshalException("index for class received, but no instance") } try cb?(v) diff --git a/swift/src/Ice/Instrumentation.swift b/swift/src/Ice/Instrumentation.swift index 7219661c0dc..3852298c7d0 100644 --- a/swift/src/Ice/Instrumentation.swift +++ b/swift/src/Ice/Instrumentation.swift @@ -27,7 +27,7 @@ extension InputStream { public func read() throws -> InstrumentationThreadState { let rawValue: UInt8 = try read(enumMaxValue: 3) guard let val = InstrumentationThreadState(rawValue: rawValue) else { - throw MarshalException(reason: "invalid enum value") + throw MarshalException("invalid enum value") } return val } @@ -94,7 +94,7 @@ extension InputStream { public func read() throws -> InstrumentationConnectionState { let rawValue: UInt8 = try read(enumMaxValue: 4) guard let val = InstrumentationConnectionState(rawValue: rawValue) else { - throw MarshalException(reason: "invalid enum value") + throw MarshalException("invalid enum value") } return val } diff --git a/swift/src/Ice/LocalException.swift b/swift/src/Ice/LocalException.swift index b940ce5b151..68e87898d11 100644 --- a/swift/src/Ice/LocalException.swift +++ b/swift/src/Ice/LocalException.swift @@ -1,1030 +1,44 @@ // Copyright (c) ZeroC, Inc. -import Foundation - -/// This exception is raised when a failure occurs during initialization. -open class InitializationException: LocalException { - /// The reason for the failure. - public var reason: String = "" - - public required init() { - super.init() - } - - public init(reason: String, file: String = #file, line: Int32 = #line) { - self.reason = reason - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::InitializationException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _InitializationExceptionDescription - } -} - -/// This exception indicates that a failure occurred while initializing a plug-in. -open class PluginInitializationException: LocalException { - /// The reason for the failure. - public var reason: String = "" - - public required init() { - super.init() - } - - public init(reason: String, file: String = #file, line: Int32 = #line) { - self.reason = reason - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::PluginInitializationException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _PluginInitializationExceptionDescription - } -} - -/// An attempt was made to register something more than once with the Ice run time. This exception is raised if an -/// attempt is made to register a servant, servant locator, facet, value factory, plug-in, object adapter, object, or -/// user exception factory more than once for the same ID. -open class AlreadyRegisteredException: LocalException { - /// The kind of object that could not be removed: "servant", "facet", "object", "default servant", - /// "servant locator", "value factory", "plugin", "object adapter", "object adapter with router", "replica group". - public var kindOfObject: String = "" - /// The ID (or name) of the object that is registered already. - public var id: String = "" - - public required init() { - super.init() - } - - public init( - kindOfObject: String, id: String, file: String = #file, - line: Int32 = #line - ) { - self.kindOfObject = kindOfObject - self.id = id - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::AlreadyRegisteredException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _AlreadyRegisteredExceptionDescription - } -} - -/// An attempt was made to find or deregister something that is not registered with the Ice run time or Ice locator. -/// This exception is raised if an attempt is made to remove a servant, servant locator, facet, value factory, plug-in, -/// object adapter, object, or user exception factory that is not currently registered. It's also raised if the Ice -/// locator can't find an object or object adapter when resolving an indirect proxy or when an object adapter is -/// activated. -open class NotRegisteredException: LocalException { - /// The kind of object that could not be removed: "servant", "facet", "object", "default servant", - /// "servant locator", "value factory", "plugin", "object adapter", "object adapter with router", "replica group". - public var kindOfObject: String = "" - /// The ID (or name) of the object that could not be removed. - public var id: String = "" - - public required init() { - super.init() - } - - public init( - kindOfObject: String, id: String, file: String = #file, - line: Int32 = #line - ) { - self.kindOfObject = kindOfObject - self.id = id - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::NotRegisteredException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _NotRegisteredExceptionDescription - } -} - -/// The operation can only be invoked with a twoway request. This exception is raised if an attempt is made to invoke -/// an operation with ice_oneway, ice_batchOneway, ice_datagram, or -/// ice_batchDatagram and the operation has a return value, out-parameters, or an exception specification. -open class TwowayOnlyException: LocalException { - /// The name of the operation that was invoked. - public var operation: String = "" - - public required init() { - super.init() - } - - public init(operation: String, file: String = #file, line: Int32 = #line) { - self.operation = operation - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::TwowayOnlyException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _TwowayOnlyExceptionDescription - } -} - -/// An attempt was made to clone a class that does not support cloning. This exception is raised if -/// ice_clone is called on a class that is derived from an abstract Slice class (that is, a class -/// containing operations), and the derived class does not provide an implementation of the ice_clone -/// operation (C++ only). -open class CloneNotImplementedException: LocalException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::CloneNotImplementedException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _CloneNotImplementedExceptionDescription - } -} - -/// This exception is raised if an operation call on a server raises an unknown exception. For example, for C++, this -/// exception is raised if the server throws a C++ exception that is not directly or indirectly derived from -/// Ice::LocalException or Ice::UserException. -open class UnknownException: LocalException { - /// This field is set to the textual representation of the unknown exception if available. - public var unknown: String = "" - - public required init() { - super.init() - } - - public init(unknown: String, file: String = #file, line: Int32 = #line) { - self.unknown = unknown - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::UnknownException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _UnknownExceptionDescription - } -} - -/// This exception is raised if an operation call on a server raises a local exception. Because local exceptions are -/// not transmitted by the Ice protocol, the client receives all local exceptions raised by the server as -/// UnknownLocalException. The only exception to this rule are all exceptions derived from -/// RequestFailedException, which are transmitted by the Ice protocol even though they are declared -/// local. -open class UnknownLocalException: UnknownException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::UnknownLocalException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _UnknownLocalExceptionDescription - } -} - -/// An operation raised an incorrect user exception. This exception is raised if an operation raises a user exception -/// that is not declared in the exception's throws clause. Such undeclared exceptions are not transmitted -/// from the server to the client by the Ice protocol, but instead the client just gets an UnknownUserException. -/// This is necessary in order to not violate the contract established by an operation's signature: Only local -/// exceptions and user exceptions declared in the throws clause can be raised. -open class UnknownUserException: UnknownException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::UnknownUserException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _UnknownUserExceptionDescription - } -} - -/// This exception is raised if the Communicator has been destroyed. -open class CommunicatorDestroyedException: LocalException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::CommunicatorDestroyedException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _CommunicatorDestroyedExceptionDescription - } -} - -/// This exception is raised if an attempt is made to use a deactivated ObjectAdapter. -open class ObjectAdapterDeactivatedException: LocalException { - /// Name of the adapter. - public var name: String = "" - - public required init() { - super.init() - } - - public init(name: String, file: String = #file, line: Int32 = #line) { - self.name = name - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ObjectAdapterDeactivatedException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ObjectAdapterDeactivatedExceptionDescription - } -} - -/// This exception is raised if an ObjectAdapter cannot be activated. This happens if the Locator -/// detects another active ObjectAdapter with the same adapter id. -open class ObjectAdapterIdInUseException: LocalException { - /// Adapter ID. - public var id: String = "" - - public required init() { - super.init() - } - - public init(id: String, file: String = #file, line: Int32 = #line) { - self.id = id - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ObjectAdapterIdInUseException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ObjectAdapterIdInUseExceptionDescription - } -} - -/// This exception is raised if no suitable endpoint is available. -open class NoEndpointException: LocalException { - /// The stringified proxy for which no suitable endpoint is available. - public var proxy: String = "" - - public required init() { - super.init() - } - - public init(proxy: String, file: String = #file, line: Int32 = #line) { - self.proxy = proxy - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::NoEndpointException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _NoEndpointExceptionDescription - } -} - -/// This exception is raised if there was an error while parsing a string. -open class ParseException: LocalException { - /// Describes the failure and includes the string that could not be parsed. - public var str: String = "" - - public required init() { - super.init() - } - - public init(str: String, file: String = #file, line: Int32 = #line) { - self.str = str - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ParseException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ParseExceptionDescription - } -} - -/// This exception is raised if an identity with an empty name is encountered. -open class IllegalIdentityException: LocalException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::IllegalIdentityException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _IllegalIdentityExceptionDescription - } -} - -/// This exception is raised to reject an illegal servant (typically a null servant). -open class IllegalServantException: LocalException { - /// Describes why this servant is illegal. - public var reason: String = "" - - public required init() { - super.init() - } - - public init(reason: String, file: String = #file, line: Int32 = #line) { - self.reason = reason - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::IllegalServantException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _IllegalServantExceptionDescription - } -} - -/// This exception is raised if a request failed. This exception, and all exceptions derived from -/// RequestFailedException, are transmitted by the Ice protocol, even though they are declared -/// local. -open class RequestFailedException: LocalException { - /// The identity of the Ice Object to which the request was sent. - public var id: Identity = .init() - /// The facet to which the request was sent. - public var facet: String = "" - /// The operation name of the request. - public var operation: String = "" - - public required init() { - super.init() - } - - public init( - id: Identity, - facet: String, - operation: String, - file: String = #file, - line: Int32 = #line - ) { - self.id = id - self.facet = facet - self.operation = operation - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::RequestFailedException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _RequestFailedExceptionDescription - } -} - -/// This exception is raised if an object does not exist on the server, that is, if no facets with the given identity -/// exist. -open class ObjectNotExistException: RequestFailedException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ObjectNotExistException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ObjectNotExistExceptionDescription - } -} - -/// This exception is raised if no facet with the given name exists, but at least one facet with the given identity -/// exists. -open class FacetNotExistException: RequestFailedException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::FacetNotExistException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _FacetNotExistExceptionDescription - } -} - -/// This exception is raised if an operation for a given object does not exist on the server. Typically this is caused -/// by either the client or the server using an outdated Slice specification. -open class OperationNotExistException: RequestFailedException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::OperationNotExistException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _OperationNotExistExceptionDescription - } -} - -/// This exception is raised if a system error occurred in the server or client process. There are many possible causes -/// for such a system exception. For details on the cause, SyscallException.error should be inspected. -open class SyscallException: LocalException { - /// The error number describing the system exception. For C++ and Unix, this is equivalent to errno. - /// For C++ and Windows, this is the value returned by GetLastError() or - /// WSAGetLastError(). - public var error: Int32 = 0 - - public required init() { - super.init() - } - - public init(error: Int32, file: String = #file, line: Int32 = #line) { - self.error = error - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::SyscallException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _SyscallExceptionDescription - } -} - -/// This exception indicates socket errors. -open class SocketException: SyscallException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::SocketException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _SocketExceptionDescription - } -} - -/// This exception indicates CFNetwork errors. -open class CFNetworkException: SocketException { - /// The domain of the error. - public var domain: String = "" - - public required init() { - super.init() - } - - public init( - error: Int32, domain: String, file: String = #file, line: Int32 = #line - ) { - self.domain = domain - super.init(error: error, file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::CFNetworkException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _CFNetworkExceptionDescription - } -} - -/// This exception indicates file errors. -open class FileException: SyscallException { - /// The path of the file responsible for the error. - public var path: String = "" - - public required init() { - super.init() - } - - public init( - error: Int32, path: String, file: String = #file, line: Int32 = #line - ) { - self.path = path - super.init(error: error, file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::FileException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _FileExceptionDescription - } -} - -/// This exception indicates connection failures. -open class ConnectFailedException: SocketException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ConnectFailedException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ConnectFailedExceptionDescription - } -} - -/// This exception indicates a connection failure for which the server host actively refuses a connection. -open class ConnectionRefusedException: ConnectFailedException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ConnectionRefusedException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ConnectionRefusedExceptionDescription - } -} - -/// This exception indicates a lost connection. -open class ConnectionLostException: SocketException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ConnectionLostException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ConnectionLostExceptionDescription - } -} - -/// This exception indicates a DNS problem. For details on the cause, DNSException.error should be inspected. -open class DNSException: LocalException { - /// The error number describing the DNS problem. For C++ and Unix, this is equivalent to h_errno. For - /// C++ and Windows, this is the value returned by WSAGetLastError(). - public var error: Int32 = 0 - /// The host name that could not be resolved. - public var host: String = "" - - public required init() { - super.init() - } - - public init( - error: Int32, host: String, file: String = #file, line: Int32 = #line - ) { - self.error = error - self.host = host - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::DNSException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _DNSExceptionDescription - } -} - -/// This exception indicates that a connection was aborted by the idle check. -open class ConnectionIdleException: TimeoutException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ConnectionIdleException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ConnectionIdleExceptionDescription - } -} - -/// This exception indicates a timeout condition. -open class TimeoutException: LocalException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::TimeoutException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _TimeoutExceptionDescription - } -} - -/// This exception indicates a connection establishment timeout condition. -open class ConnectTimeoutException: TimeoutException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ConnectTimeoutException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ConnectTimeoutExceptionDescription - } -} - -/// This exception indicates a connection closure timeout condition. -open class CloseTimeoutException: TimeoutException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::CloseTimeoutException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _CloseTimeoutExceptionDescription - } -} - -/// This exception indicates that an invocation failed because it timed out. -open class InvocationTimeoutException: TimeoutException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::InvocationTimeoutException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _InvocationTimeoutExceptionDescription - } -} - -/// This exception indicates that an asynchronous invocation failed because it was canceled explicitly by the user. -open class InvocationCanceledException: LocalException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::InvocationCanceledException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _InvocationCanceledExceptionDescription - } -} - -/// A generic exception base for all kinds of protocol error conditions. -open class ProtocolException: LocalException { - /// The reason for the failure. - public var reason: String = "" - - public required init() { - super.init() - } - - public init(reason: String, file: String = #file, line: Int32 = #line) { - self.reason = reason - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ProtocolException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ProtocolExceptionDescription - } -} - -/// This exception indicates that the connection has been gracefully shut down by the server. The operation call that -/// caused this exception has not been executed by the server. In most cases you will not get this exception, because -/// the client will automatically retry the operation call in case the server shut down the connection. However, if -/// upon retry the server shuts down the connection again, and the retry limit has been reached, then this exception is -/// propagated to the application code. -open class CloseConnectionException: ProtocolException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::CloseConnectionException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _CloseConnectionExceptionDescription - } -} - -/// This exception is raised by an operation call if the application closes the connection locally using -/// Connection.close. -open class ConnectionManuallyClosedException: LocalException { - /// True if the connection was closed gracefully, false otherwise. - public var graceful: Bool = false - - public required init() { - super.init() - } - - public init(graceful: Bool, file: String = #file, line: Int32 = #line) { - self.graceful = graceful - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::ConnectionManuallyClosedException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _ConnectionManuallyClosedExceptionDescription - } -} - -/// A datagram exceeds the configured size. This exception is raised if a datagram exceeds the configured send or -/// receive buffer size, or exceeds the maximum payload size of a UDP packet (65507 bytes). -open class DatagramLimitException: ProtocolException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::DatagramLimitException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _DatagramLimitExceptionDescription - } -} - -/// This exception is raised for errors during marshaling or unmarshaling data. -open class MarshalException: ProtocolException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::MarshalException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _MarshalExceptionDescription - } -} - -/// This exception is raised if an unsupported feature is used. The unsupported feature string contains the name of the -/// unsupported feature. -open class FeatureNotSupportedException: LocalException { - /// The name of the unsupported feature. - public var unsupportedFeature: String = "" - - public required init() { - super.init() - } - - public init(unsupportedFeature: String, file: String = #file, line: Int32 = #line) { - self.unsupportedFeature = unsupportedFeature - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::FeatureNotSupportedException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _FeatureNotSupportedExceptionDescription - } -} - -/// This exception indicates a failure in a security subsystem, such as the IceSSL plug-in. -open class SecurityException: LocalException { - /// The reason for the failure. - public var reason: String = "" - - public required init() { - super.init() - } - - public init(reason: String, file: String = #file, line: Int32 = #line) { - self.reason = reason - super.init(file: file, line: line) - } - - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::SecurityException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _SecurityExceptionDescription - } -} - -/// This exception indicates that an attempt has been made to change the connection properties of a fixed proxy. -open class FixedProxyException: LocalException { - /// Returns the Slice type ID of this exception. - /// - /// - returns: `String` - the Slice type ID of this exception. - override open class func ice_staticId() -> String { - return "::Ice::FixedProxyException" - } - - /// Returns a string representation of this exception - /// - /// - returns: `String` - The string representaton of this exception. - override open func ice_print() -> String { - return _FixedProxyExceptionDescription +/// Base class for Ice local exceptions. +open class LocalException: Exception, CustomStringConvertible { + public let message: String + public let file: String + public let line: Int32 + private let cxxDescription: String? + + /// A textual representation of this Ice exception. + public var description: String { cxxDescription ?? "\(file):\(line) \(ice_id()) \(message)" } + + /// Creates a LocalException. + /// - Parameters: + /// - message: The exception message. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public init(_ message: String, file: String = #fileID, line: Int32 = #line) { + self.message = message + self.file = file + self.line = line + self.cxxDescription = nil + } + + /// Creates a LocalException from an Ice C++ local exception. + /// - Parameters: + /// - message: The exception message. + /// - cxxDescription: The C++ exception description. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public required init(message: String, cxxDescription: String, file: String, line: Int32) { + self.message = message + self.file = file + self.line = line + self.cxxDescription = cxxDescription + } + + /// Gets the type ID of the class, for example "::Ice::CommunicatorDestroyedException". + /// This type ID is provided for informational purposes. + /// - Returns: The type ID of the class. + public func ice_id() -> String { + "::" + String(reflecting: type(of: self)).replacingOccurrences(of: ".", with: "::") } } diff --git a/swift/src/Ice/LocalExceptionDescription.swift b/swift/src/Ice/LocalExceptionDescription.swift deleted file mode 100644 index 19788cc8c9d..00000000000 --- a/swift/src/Ice/LocalExceptionDescription.swift +++ /dev/null @@ -1,488 +0,0 @@ -// Copyright (c) ZeroC, Inc. - -import IceImpl - -extension String { - fileprivate mutating func sep(_ str: String) { - guard !str.isEmpty else { - return - } - append(":\n\(str)") - } - - fileprivate mutating func nl(_ str: String) { - guard !str.isEmpty else { - return - } - append("\n\(str)") - } - - fileprivate mutating func failedRequest(_ ex: RequestFailedException) { - let id = ex.id.name.isEmpty ? "" : identityToString(id: ex.id, mode: .Unicode) - sep("identity: `\(id)'") - nl("facet: \(ex.facet)") - nl("operation: \(ex.operation)") - } - - fileprivate mutating func hex(_ value: UInt8) { - append("0x") - append(String(format: "%02X", value)) - } -} - -private func socketError(_ error: Int32) -> String { - if error == 0 { - return "unknown error" - } - return ICEUtil.errorToString(error) -} - -extension InitializationException { - var _InitializationExceptionDescription: String { - var s = String() - - s.sep("initialization exception") - s.sep(reason) - - return s - } -} - -extension PluginInitializationException { - var _PluginInitializationExceptionDescription: String { - var s = String() - - s.sep("plug-in initialization failed") - s.sep(reason) - - return s - } -} - -extension AlreadyRegisteredException { - var _AlreadyRegisteredExceptionDescription: String { - var s = String() - - s.sep("\(kindOfObject) with ice `\(id)' is already registered") - - return s - } -} - -extension NotRegisteredException { - var _NotRegisteredExceptionDescription: String { - var s = String() - - s.sep("no \(kindOfObject) with id `\(id)' is registered") - - return s - } -} - -extension TwowayOnlyException { - var _TwowayOnlyExceptionDescription: String { - var s = String() - - s.sep("operation `\(operation)' can only be invoked as a twoway request") - - return s - } -} - -extension CloneNotImplementedException { - var _CloneNotImplementedExceptionDescription: String { - var s = String() - - s.sep("ice_clone() must be implemented in classes derived from abstract base classes") - - return s - } -} - -extension UnknownException { - var _UnknownExceptionDescription: String { - var s = String() - - s.sep("unknown exception") - s.sep(unknown) - - return s - } -} - -extension UnknownLocalException { - var _UnknownLocalExceptionDescription: String { - var s = String() - - s.sep("unknown local exception") - s.sep(unknown) - - return s - } -} - -extension UnknownUserException { - var _UnknownUserExceptionDescription: String { - var s = String() - - s.sep("unknown user exception") - s.sep(unknown) - - return s - } -} - -extension CommunicatorDestroyedException { - var _CommunicatorDestroyedExceptionDescription: String { - var s = String() - - s.sep("communicator object destroyed") - - return s - } -} - -extension ObjectAdapterDeactivatedException { - var _ObjectAdapterDeactivatedExceptionDescription: String { - var s = String() - - s.sep("object adapter `\(name)' deactivated") - - return s - } -} - -extension ObjectAdapterIdInUseException { - var _ObjectAdapterIdInUseExceptionDescription: String { - var s = String() - - s.sep("object adapter with id `\(id)' is already in use") - - return s - } -} - -extension NoEndpointException { - var _NoEndpointExceptionDescription: String { - var s = String() - - s.sep("no suitable endpoint available for proxy `\(proxy)'") - - return s - } -} - -extension ParseException { - var _ParseExceptionDescription: String { - var s = String() - - s.sep("error while parsing: `\(str)'") - - return s - } -} - -extension IllegalIdentityException { - var _IllegalIdentityExceptionDescription: String { - var s = String() - - s.sep("an identity with an empty name is not allowed") - - return s - } -} - -extension IllegalServantException { - var _IllegalServantExceptionDescription: String { - var s = String() - - s.sep("illegal servant: `\(reason)'") - - return s - } -} - -extension RequestFailedException { - var _RequestFailedExceptionDescription: String { - var s = String() - - s.sep("request failed") - s.failedRequest(self) - - return s - } -} - -extension ObjectNotExistException { - var _ObjectNotExistExceptionDescription: String { - var s = String() - - s.sep("object does not exist") - s.failedRequest(self) - - return s - } -} - -extension FacetNotExistException { - var _FacetNotExistExceptionDescription: String { - var s = String() - - s.sep("facet does not exist") - s.failedRequest(self) - - return s - } -} - -extension OperationNotExistException { - var _OperationNotExistExceptionDescription: String { - var s = String() - - s.sep("operation does not exist") - s.failedRequest(self) - - return s - } -} - -extension SyscallException { - var _SyscallExceptionDescription: String { - var s = String() - - if error != 0 { - s.sep("syscall exception: \(ICEUtil.errorToString(error))") - } - - return s - } -} - -extension SocketException { - var _SocketExceptionDescription: String { - var s = String() - - s.sep("socket exception: \(socketError(error))") - - return s - } -} - -extension CFNetworkException { - var _CFNetworkExceptionDescription: String { - var s = String() - - s.sep("network exception: domain: `\(domain)' error: `\(error)'") - - return s - } -} - -extension FileException { - var _FileExceptionDescription: String { - var s = String() - - s.sep("file exception: ") - if error == 0 { - s.append("couldn't open file") - } else { - s.append(ICEUtil.errorToString(error)) - } - if !path.isEmpty { - s.nl("path: \(path)") - } - - return s - } -} - -extension ConnectFailedException { - var _ConnectFailedExceptionDescription: String { - var s = String() - - s.sep("connect failed: \(socketError(error))") - - return s - } -} - -extension ConnectionRefusedException { - var _ConnectionRefusedExceptionDescription: String { - var s = String() - - s.sep("connection refused: \(socketError(error))") - - return s - } -} - -extension ConnectionLostException { - var _ConnectionLostExceptionDescription: String { - var s = String() - - s.sep("connection lost: ") - if error == 0 { - s.append("recv() returned zero") - } else { - s.append(socketError(error)) - } - - return s - } -} - -extension DNSException { - var _DNSExceptionDescription: String { - var s = String() - - s.sep("DNS error: \(ICEUtil.errorToStringDNS(error))") - s.nl("host: \(host)") - - return s - } -} - -extension TimeoutException { - var _TimeoutExceptionDescription: String { - var s = String() - - s.sep("timeout while sending or receiving data") - - return s - } -} - -extension ConnectTimeoutException { - var _ConnectTimeoutExceptionDescription: String { - var s = String() - - s.sep("timeout while establishing a connection") - - return s - } -} - -extension CloseTimeoutException { - var _CloseTimeoutExceptionDescription: String { - var s = String() - - s.sep("timeout while closing a connection") - - return s - } -} - -extension ConnectionIdleException { - var _ConnectionIdleExceptionDescription: String { - var s = String() - - s.sep("connection aborted by the idle check") - - return s - } -} - -extension InvocationTimeoutException { - var _InvocationTimeoutExceptionDescription: String { - var s = String() - - s.sep("invocation has timed out") - - return s - } -} - -extension InvocationCanceledException { - var _InvocationCanceledExceptionDescription: String { - var s = String() - - s.sep("invocation canceled") - - return s - } -} - -extension ProtocolException { - var _ProtocolExceptionDescription: String { - var s = String() - - s.sep("protocol exception") - s.sep(reason) - - return s - } -} -extension CloseConnectionException { - var _CloseConnectionExceptionDescription: String { - var s = String() - - s.sep("protocol error: connection closed") - s.sep(reason) - - return s - } -} - -extension ConnectionManuallyClosedException { - var _ConnectionManuallyClosedExceptionDescription: String { - var s = String() - - let type = graceful ? "gracefully" : "forcefully" - s.sep("protocol error: connection manually closed (\(type))") - - return s - } -} - -extension DatagramLimitException { - var _DatagramLimitExceptionDescription: String { - var s = String() - - s.sep("protocol error: maximum datagram payload size exceeded") - s.sep(reason) - - return s - } -} - -extension MarshalException { - var _MarshalExceptionDescription: String { - var s = String() - - s.sep("protocol error: error during marshaling or unmarshaling") - s.sep(reason) - - return s - } -} - -extension FeatureNotSupportedException { - var _FeatureNotSupportedExceptionDescription: String { - var s = String() - - s.sep("feature: `\(unsupportedFeature)' is not supported") - - return s - } -} - -extension SecurityException { - var _SecurityExceptionDescription: String { - var s = String() - - s.sep("security exception") - s.sep(reason) - - return s - } -} - -extension FixedProxyException { - var _FixedProxyExceptionDescription: String { - var s = String() - - s.sep("fixed proxy exception") - - return s - } -} diff --git a/swift/src/Ice/LocalExceptionFactory.swift b/swift/src/Ice/LocalExceptionFactory.swift index 4d5c6f3773a..09848250d71 100644 --- a/swift/src/Ice/LocalExceptionFactory.swift +++ b/swift/src/Ice/LocalExceptionFactory.swift @@ -2,206 +2,59 @@ import IceImpl -class ExceptionFactory: ICEExceptionFactory { - static func initializationException(_ reason: String, file: String, line: Int32) -> Error { - return InitializationException(reason: reason, file: file, line: line) - } - - static func pluginInitializationException(_ reason: String, file: String, line: Int32) -> Error { - return PluginInitializationException(reason: reason, file: file, line: line) - } - - static func alreadyRegisteredException( - _ kindOfObject: String, id: String, file: String, line: Int32 - ) -> Error { - return AlreadyRegisteredException(kindOfObject: kindOfObject, id: id, file: file, line: line) - } - - static func notRegisteredException(_ kindOfObject: String, id: String, file: String, line: Int32) - -> Error - { - return NotRegisteredException(kindOfObject: kindOfObject, id: id, file: file, line: line) - } - - static func twowayOnlyException(_ operation: String, file: String, line: Int32) -> Error { - return TwowayOnlyException(operation: operation, file: file, line: line) - } - - static func communicatorDestroyedException(_ file: String, line: Int32) -> Error { - return CommunicatorDestroyedException(file: file, line: line) - } - - static func objectAdapterDeactivatedException(_ name: String, file: String, line: Int32) -> Error { - return ObjectAdapterDeactivatedException(name: name, file: file, line: line) - } - - static func objectAdapterIdInUseException(_ id: String, file: String, line: Int32) -> Error { - return ObjectAdapterIdInUseException(id: id, file: file, line: line) - } - - static func noEndpointException(_ proxy: String, file: String, line: Int32) -> Error { - return NoEndpointException(proxy: proxy, file: file, line: line) - } - - static func parseException(_ str: String, file: String, line: Int32) -> Error { - return ParseException(str: str, file: file, line: line) - } - - static func illegalIdentityException(_ file: String, line: Int32) -> Error { - return IllegalIdentityException(file: file, line: line) - } - - static func illegalServantException(_ reason: String, file: String, line: Int32) -> Error { - return IllegalServantException(reason: reason, file: file, line: line) - } - - static func dNSException(_ error: Int32, host: String, file: String, line: Int32) -> Error { - return DNSException(error: error, host: host, file: file, line: line) - } - - static func invocationCanceledException(_ file: String, line: Int32) -> Error { - return InvocationCanceledException(file: file, line: line) - } - - static func featureNotSupportedException(_ unsupportedFeature: String, file: String, line: Int32) - -> Error - { - return FeatureNotSupportedException( - unsupportedFeature: unsupportedFeature, file: file, line: line) - } - - static func fixedProxyException(_ file: String, line: Int32) -> Error { - return FixedProxyException(file: file, line: line) - } - - static func securityException(_ reason: String, file: String, line: Int32) -> Error { - return SecurityException(reason: reason, file: file, line: line) - } - - static func localException(_ file: String, line: Int32) -> Error { - return LocalException(file: file, line: line) - } - - static func unknownLocalException(_ unknown: String, file: String, line: Int32) -> Error { - return UnknownLocalException(unknown: unknown, file: file, line: line) - } - - static func unknownUserException(_ unknown: String, file: String, line: Int32) -> Error { - return UnknownUserException(unknown: unknown, file: file, line: line) - } - - static func unknownException(_ unknown: String, file: String, line: Int32) -> Error { - return UnknownException(unknown: unknown, file: file, line: line) - } - - static func objectNotExistException( - _ name: String, category: String, facet: String, operation: String, - file: String, line: Int32 - ) -> Error { - return ObjectNotExistException( - id: Identity(name: name, category: category), facet: facet, operation: operation, - file: file, line: line) - } - - static func facetNotExistException( - _ name: String, category: String, facet: String, operation: String, - file: String, line: Int32 +class LocalExceptionFactory: ICELocalExceptionFactory { + static func requestFailedException( + _ typeId: String, name: String, category: String, facet: String, operation: String, + message: String, cxxDescription: String, file: String, line: Int32 ) -> Error { - return FacetNotExistException( - id: Identity(name: name, category: category), facet: facet, operation: operation, - file: file, line: line) - } - - static func operationNotExistException( - _ name: String, - category: String, - facet: String, - operation: String, file: String, line: Int32 + let className = typeId.dropFirst(2).replacingOccurrences(of: "::", with: ".") + if let requestFailedExceptionType = NSClassFromString(className) as? RequestFailedException.Type { + return requestFailedExceptionType.init( + id: Identity(name: name, category: category), facet: facet, operation: operation, message: message, + cxxDescription: cxxDescription, file: file, line: line) + } else { + fatalError("unexpected RequestFailedException type: \(typeId)") + } + } + + static func registeredException( + _ typeId: String, kindOfObject: String, objectId: String, message: String, cxxDescription: String, file: String, + line: Int32 ) -> Error { - return OperationNotExistException( - id: Identity( - name: name, - category: category), - facet: facet, - operation: operation, file: file, line: line) - } - - static func requestFailedException( - _ name: String, category: String, facet: String, operation: String, - file: String, line: Int32 + switch typeId { + case "::Ice::AlreadyRegisteredException": + AlreadyRegisteredException( + kindOfObject: kindOfObject, id: objectId, message: message, cxxDescription: cxxDescription, file: file, + line: line) + case "::Ice::NotRegisteredException": + NotRegisteredException( + kindOfObject: kindOfObject, id: objectId, message: message, cxxDescription: cxxDescription, file: file, + line: line) + default: + fatalError("unexpected XxxRegisteredException type: \(typeId)") + } + } + + static func connectionManuallyClosedException( + _ graceful: Bool, message: String, cxxDescription: String, file: String, line: Int32 ) -> Error { - return RequestFailedException( - id: Identity(name: name, category: category), facet: facet, operation: operation, - file: file, line: line) - } - - static func connectionRefusedException(_ error: Int32, file: String, line: Int32) -> Error { - return ConnectionRefusedException(error: error, file: file, line: line) - } - - static func fileException(_ error: Int32, path: String, file: String, line: Int32) -> Error { - return FileException(error: error, path: path, file: file, line: line) + ConnectionManuallyClosedException( + graceful: graceful, message: message, cxxDescription: cxxDescription, file: file, line: line) } - static func connectFailedException(_ error: Int32, file: String, line: Int32) -> Error { - return ConnectionRefusedException(error: error, file: file, line: line) - } - - static func connectionLostException(_ error: Int32, file: String, line: Int32) -> Error { - return ConnectionLostException(error: error, file: file, line: line) - } - - static func socketException(_ error: Int32, file: String, line: Int32) -> Error { - return SocketException(error: error, file: file, line: line) - } - - static func syscallException(_ error: Int32, file: String, line: Int32) -> Error { - return SyscallException(error: error, file: file, line: line) - } - - static func connectionIdleException(_ file: String, line: Int32) -> Error { - return ConnectionIdleException(file: file, line: line) - } - - static func connectTimeoutException(_ file: String, line: Int32) -> Error { - return ConnectTimeoutException(file: file, line: line) - } - - static func closeTimeoutException(_ file: String, line: Int32) -> Error { - return CloseTimeoutException(file: file, line: line) - } - - static func invocationTimeoutException(_ file: String, line: Int32) -> Error { - return InvocationTimeoutException(file: file, line: line) - } - - static func timeoutException(_ file: String, line: Int32) -> Error { - return TimeoutException(file: file, line: line) - } - - static func closeConnectionException(_ reason: String, file: String, line: Int32) -> Error { - return CloseConnectionException(reason: reason, file: file, line: line) - } - - static func connectionManuallyClosedException(_ graceful: Bool, file: String, line: Int32) + static func localException(_ typeId: String, message: String, cxxDescription: String, file: String, line: Int32) -> Error { - return ConnectionManuallyClosedException(graceful: graceful, file: file, line: line) - } - - static func datagramLimitException(_ reason: String, file: String, line: Int32) -> Error { - return DatagramLimitException(reason: reason, file: file, line: line) - } - - static func marshalException(_ reason: String, file: String, line: Int32) -> Error { - return MarshalException(reason: reason, file: file, line: line) - } - - static func protocolException(_ reason: String, file: String, line: Int32) -> Error { - return ProtocolException(reason: reason, file: file, line: line) + let className = typeId.dropFirst(2).replacingOccurrences(of: "::", with: ".") + return if let localExceptionType = NSClassFromString(className) as? LocalException.Type { + localExceptionType.init(message: message, cxxDescription: cxxDescription, file: file, line: line) + } else { + CxxLocalException(typeId: typeId, message: message, cxxDescription: cxxDescription, file: file, line: line) + } } - static func runtimeError(_ message: String) -> Error { - return RuntimeError(message) + static func cxxException(_ typeName: String, message: String) -> Error { + CxxLocalException( + typeId: typeName, message: message, cxxDescription: "\(typeName) \(message)", file: "???", line: 0) } } diff --git a/swift/src/Ice/LocalExceptions.swift b/swift/src/Ice/LocalExceptions.swift new file mode 100644 index 00000000000..f60f9721fe1 --- /dev/null +++ b/swift/src/Ice/LocalExceptions.swift @@ -0,0 +1,421 @@ +// Copyright (c) ZeroC, Inc. + +// This file contains all the exception classes derived from LocalException defined in the Ice module. + +// +// The 6 (7 with the RequestFailedException base class) special local exceptions that can be marshaled in an Ice reply +// message. Other local exceptions can't be marshaled. +// + +/// The base exception for the 3 NotExist exceptions. +public class RequestFailedException: LocalException { + /// The identity of the Ice Object to which the request was sent. + public let id: Identity + /// The facet to which the request was sent. + public let facet: String + /// The operation name of the request. + public let operation: String + + /// Creates a XxxNotExistException from an Ice C++ exception. + /// - Parameters: + /// - id: The identity of the target Ice object carried by the request. + /// - facet: The facet of the target Ice object. + /// - operation: The operation name carried by the request. + /// - message: The exception message. + /// - cxxDescription: The C++ exception description. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public required init( + id: Identity, facet: String, operation: String, message: String, cxxDescription: String, file: String, + line: Int32 + ) { + self.id = id + self.facet = facet + self.operation = operation + super.init(message: message, cxxDescription: cxxDescription, file: file, line: line) + } + + /// Internal initializer - don't use. + public required init(message: String, cxxDescription: String, file: String, line: Int32) { + fatalError("RequestFailedException must be initialized with an id, facet, and operation") + } + + internal init(typeName: String, id: Identity, facet: String, operation: String, file: String, line: Int32) { + self.id = id + self.facet = facet + self.operation = operation + super.init( + Self.makeMessage(typeName: typeName, id: id, facet: facet, operation: operation), file: file, line: line) + } + + override internal init(_ message: String, file: String, line: Int32) { + self.id = Identity() + self.facet = "" + self.operation = "" + super.init(message, file: file, line: line) + } + + internal class func makeMessage(typeName: String, id: Identity, facet: String, operation: String) -> String { + "dispatch failed for \(typeName) { id = '\(identityToString(id: id))', facet = '\(facet)', operation = '\(operation)' }" + } +} + +/// The dispatch could not find a servant for the identity carried by the request. +public final class ObjectNotExistException: RequestFailedException { + /// Creates an ObjectNotExistException. + /// - Parameters: + /// - id: The identity of the target Ice object carried by the request. + /// - facet: The facet of the target Ice object. + /// - operation: The operation name carried by the request. + /// - message: The exception message. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(id: Identity, facet: String, operation: String, file: String = #fileID, line: Int32 = #line) + { + self.init( + typeName: "ObjectNotExistException", id: id, facet: facet, operation: operation, file: file, line: line) + } + + /// Creates an ObjectNotExistException. The request details (id, facet, operation) will be filled-in by the Ice + /// runtime when the exception is marshaled. + /// - Parameters: + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(file: String = #fileID, line: Int32 = #line) { + self.init("dispatch failed with ObjectNotExistException", file: file, line: line) + } +} + +/// The dispatch could not find a servant for the identity + facet carried by the request. +public final class FacetNotExistException: RequestFailedException { + /// Creates a FacetNotExistException. + /// - Parameters: + /// - id: The identity of the target Ice object carried by the request. + /// - facet: The facet of the target Ice object. + /// - operation: The operation name carried by the request. + /// - message: The exception message. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(id: Identity, facet: String, operation: String, file: String = #fileID, line: Int32 = #line) + { + self.init( + typeName: "FacetNotExistException", id: id, facet: facet, operation: operation, file: file, line: line) + } + + /// Creates a FacetNotExistException. The request details (id, facet, operation) will be filled-in by the Ice + /// runtime when the exception is marshaled. + /// - Parameters: + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(file: String = #fileID, line: Int32 = #line) { + self.init("dispatch failed with FacetNotExistException", file: file, line: line) + } +} + +/// The dispatch could not find the operation carried by the request on the target servant. This is typically due +/// to a mismatch in the Slice definitions, such as the client using Slice definitions newer than the server's. +public final class OperationNotExistException: RequestFailedException { + /// Creates an OperationNotExistException. + /// - Parameters: + /// - id: The identity of the target Ice object carried by the request. + /// - facet: The facet of the target Ice object. + /// - operation: The operation name carried by the request. + /// - message: The exception message. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(id: Identity, facet: String, operation: String, file: String = #fileID, line: Int32 = #line) + { + self.init( + typeName: "OperationNotExistException", id: id, facet: facet, operation: operation, file: file, line: line) + } + + /// Creates an OperationNotExistException. The request details (id, facet, operation) will be filled-in by the Ice + /// runtime when the exception is marshaled. + /// - Parameters: + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(file: String = #fileID, line: Int32 = #line) { + self.init("dispatch failed with OperationNotExistException", file: file, line: line) + } +} + +/// The dispatch failed with an exception that is not an `Ice.LocalException` or an `Ice.UserException`. +public class UnknownException: LocalException { + @available(*, deprecated, renamed: "message") + public var reason: String { message } +} + +/// The dispatch failed with an `Ice.LocalException` that is not one of the special marshal-able local exceptions. +public final class UnknownLocalException: UnknownException {} + +/// The dispatch returned an `Ice.UserException` that was not declared in the operation's exception specification. +public final class UnknownUserException: UnknownException { + /// Creates an UnknownUserException. + /// - Parameters: + /// - badTypeId: The type ID of the user exception carried by the reply. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(badTypeId: String, file: String = #fileID, line: Int32 = #line) { + self.init( + "the user exception carried by the reply does not conform to the operation's exception specification: \(badTypeId)", + file: file, line: line) + } +} + +// +// Protocol exceptions +// + +/// The base class for Ice protocol exceptions. +public class ProtocolException: LocalException {} + +/// This exception indicates that the connection has been gracefully shut down by the server. The operation call that +/// caused this exception has not been executed by the server. In most cases you will not get this exception, because +/// the client will automatically retry the operation call in case the server shut down the connection. However, if +/// upon retry the server shuts down the connection again, and the retry limit has been reached, then this exception is +/// propagated to the application code. +public final class CloseConnectionException: ProtocolException {} + +/// A datagram exceeds the configured size. This exception is raised if a datagram exceeds the configured send or +/// receive buffer size, or exceeds the maximum payload size of a UDP packet (65507 bytes). +public final class DatagramLimitException: ProtocolException {} + +/// This exception is raised for errors during marshaling or unmarshaling data. +public final class MarshalException: ProtocolException {} + +// +// Timeout exceptions +// + +/// This exception indicates a timeout condition. +public class TimeoutException: LocalException {} + +/// This exception indicates a connection establishment timeout condition. +public final class ConnectTimeoutException: TimeoutException {} + +/// This exception indicates a connection closure timeout condition. +public final class CloseTimeoutException: TimeoutException {} + +/// This exception indicates that an invocation failed because it timed out. +public final class InvocationTimeoutException: TimeoutException {} + +// +// Syscall exceptions +// + +/// This exception is raised if a system error occurred in the server or client process. +public class SyscallException: LocalException {} + +/// This exception indicates a DNS problem. +public final class DNSException: SyscallException {} + +// +// Socket exceptions +// + +/// This exception indicates a socket error. +public class SocketException: SyscallException {} + +/// This exception indicates a connection failure. +public class ConnectFailedException: SocketException {} + +/// This exception indicates a connection failure for which the server host actively refuses a connection. +public final class ConnectionRefusedException: ConnectFailedException {} + +/// This exception indicates a lost connection. +public final class ConnectionLostException: SocketException {} + +// +// Other leaf local exceptions in alphabetical order. +// + +/// An attempt was made to register something more than once with the Ice run time. This exception is raised if an +/// attempt is made to register a servant, servant locator, facet, value factory, plug-in, object adapter, object, or +/// user exception factory more than once for the same ID. +public final class AlreadyRegisteredException: LocalException { + /// The kind of object that could not be removed: "servant", "facet", "object", "default servant", + /// "servant locator", "value factory", "plugin", "object adapter", "object adapter with router", "replica group". + public let kindOfObject: String + + /// The ID (or name) of the object that is registered already. + public let id: String + + /// Creates an AlreadyRegisteredException. + /// - Parameters: + /// - kindOfObject: The kind of object that is already registered. + /// - id: The ID (or name) of the object that is already registered. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public init(kindOfObject: String, id: String, file: String = #fileID, line: Int32 = #line) { + self.kindOfObject = kindOfObject + self.id = id + super.init("another \(kindOfObject) is already registered with ID '\(id)'", file: file, line: line) + } + + /// Internal initializer - don't use. + public required init(message: String, cxxDescription: String, file: String, line: Int32) { + fatalError("AlreadyRegisteredException must be initialized with a kindOfObject and id") + } + + // Initializer for C++ exceptions + internal init(kindOfObject: String, id: String, message: String, cxxDescription: String, file: String, line: Int32) + { + self.kindOfObject = kindOfObject + self.id = id + super.init(message: message, cxxDescription: cxxDescription, file: file, line: line) + } +} + +/// This exception is raised if the Communicator has been destroyed. +public final class CommunicatorDestroyedException: LocalException {} + +/// This exception indicates that a connection was aborted by the idle check. +public class ConnectionIdleException: LocalException {} + +/// To be removed +public final class ConnectionManuallyClosedException: LocalException { + public var graceful: Bool + + public init(graceful: Bool, file: String = #fileID, line: Int32 = #line) { + self.graceful = graceful + super.init("connection was manually closed", file: file, line: line) + } + + public required init(message: String, cxxDescription: String, file: String, line: Int32) { + fatalError("ConnectionManuallyClosedException must be initialized with a graceful flag") + } + + internal init(graceful: Bool, message: String, cxxDescription: String, file: String, line: Int32) { + self.graceful = graceful + super.init(message: message, cxxDescription: cxxDescription, file: file, line: line) + } +} + +/// Represents a C++ local exception or a std::exception without its own corresponding Swift class. +internal final class CxxLocalException: LocalException { + private let typeId: String + + override public func ice_id() -> String { typeId } + + internal init(typeId: String, message: String, cxxDescription: String, file: String, line: Int32) { + self.typeId = typeId + super.init(message: message, cxxDescription: cxxDescription, file: file, line: line) + } + + internal required init(message: String, cxxDescription: String, file: String, line: Int32) { + fatalError("CxxLocalException must be initialized with a typeId") + } +} + +/// This exception is raised if an unsupported feature is used. +public final class FeatureNotSupportedException: LocalException {} + +/// This exception indicates that an attempt has been made to change the connection properties of a fixed proxy. +public final class FixedProxyException: LocalException {} + +/// This exception is raised when a failure occurs during initialization. +public final class InitializationException: LocalException {} + +/// This exception indicates that an asynchronous invocation failed because it was canceled explicitly by the user. +public final class InvocationCanceledException: LocalException {} + +/// This exception is raised if no suitable endpoint is available. +public final class NoEndpointException: LocalException { + /// Creates a NoEndpointException. + /// - Parameters: + /// - proxy: The proxy that carries the endpoints. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(proxy: ObjectPrx, file: String = #fileID, line: Int32 = #line) { + self.init("no suitable endpoint available for proxy '\(proxy)'", file: file, line: line) + } +} + +/// An attempt was made to find or deregister something that is not registered with the Ice run time or Ice locator. +/// This exception is raised if an attempt is made to remove a servant, servant locator, facet, value factory, plug-in, +/// object adapter, object, or user exception factory that is not currently registered. It's also raised if the Ice +/// locator can't find an object or object adapter when resolving an indirect proxy or when an object adapter is +/// activated. +public final class NotRegisteredException: LocalException { + /// The kind of object that could not be removed: "servant", "facet", "object", "default servant", + /// "servant locator", "value factory", "plugin", "object adapter", "object adapter with router", "replica group". + public let kindOfObject: String + + /// The ID (or name) of the object that could not be removed. + public let id: String + + /// Creates a NotRegisteredException. + /// - Parameters: + /// - kindOfObject: The kind of object that is not registered. + /// - id: The ID (or name) of the object that is not registered. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public init(kindOfObject: String, id: String, file: String = #fileID, line: Int32 = #line) { + self.kindOfObject = kindOfObject + self.id = id + super.init("no \(kindOfObject) is registered with ID '\(id)'", file: file, line: line) + } + + /// Internal initializer - don't use. + public required init(message: String, cxxDescription: String, file: String, line: Int32) { + fatalError("NotRegisteredException must be initialized with a kindOfObject and id") + } + + // Initializer for C++ exceptions + internal init(kindOfObject: String, id: String, message: String, cxxDescription: String, file: String, line: Int32) + { + self.kindOfObject = kindOfObject + self.id = id + super.init(message: message, cxxDescription: cxxDescription, file: file, line: line) + } +} + +/// This exception is raised if an attempt is made to use a deactivated ObjectAdapter. +public final class ObjectAdapterDeactivatedException: LocalException { + /// Creates an ObjectAdapterDeactivatedException. + /// - Parameters: + /// - name: The name of the object adapter. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(name: String, file: String = #fileID, line: Int32 = #line) { + self.init("object adapter '\(name)' is deactivated", file: file, line: line) + } +} + +/// This exception is raised if an ObjectAdapter cannot be activated. This happens if the Locator +/// detects another active ObjectAdapter with the same adapter id. +public final class ObjectAdapterIdInUseException: LocalException { + /// Creates an ObjectAdapterIdInUseException. + /// - Parameters: + /// - id: The adapter ID that is already active in the Locator. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(id: String, file: String = #fileID, line: Int32 = #line) { + self.init("an object adapter with adapter ID'\(id)' is already active", file: file, line: line) + } +} + +/// This exception is raised if there was an error while parsing a string. +public final class ParseException: LocalException {} + +/// This exception indicates that a failure occurred while initializing a plug-in. +public final class PluginInitializationException: LocalException {} + +/// This exception indicates a failure in a security subsystem, such as the IceSSL plug-in. +public final class SecurityException: LocalException {} + +/// The operation can only be invoked with a twoway request. This exception is raised if an attempt is made to invoke +/// an operation with ice_oneway, ice_batchOneway, ice_datagram, or +/// ice_batchDatagram and the operation has a return value, out-parameters, or an exception specification. +public final class TwowayOnlyException: LocalException { + /// Creates a TwowayOnlyException. + /// - Parameters: + /// - operation: The name of the two-way only operation. + /// - file: The file where the exception was thrown. + /// - line: The line where the exception was thrown. + public convenience init(operation: String, file: String = #fileID, line: Int32 = #line) { + self.init( + "cannot invoke operation '\(operation)' with a oneway, batchOneway, datagram, or batchDatagram proxy", + file: file, line: line) + } +} diff --git a/swift/src/Ice/OutgoingResponse.swift b/swift/src/Ice/OutgoingResponse.swift index 09989c7ab35..3e7fc80f204 100644 --- a/swift/src/Ice/OutgoingResponse.swift +++ b/swift/src/Ice/OutgoingResponse.swift @@ -20,7 +20,7 @@ public final class OutgoingResponse { /// Gets the reply status of the response. public let replyStatus: ReplyStatus - /// Constructs an OutgoingResponse object. + /// Creates an OutgoingResponse object. /// - Parameters: /// - replyStatus: The reply status. /// - exceptionId: The ID of the exception, when the response carries an exception. @@ -33,7 +33,7 @@ public final class OutgoingResponse { self.outputStream = outputStream } - /// Constructs an OutgoingResponse object with the ok status. + /// Creates an OutgoingResponse object with the ok status. /// - Parameter outputStream: The output stream that holds the response. public convenience init(_ outputStream: OutputStream) { self.init(replyStatus: .ok, exceptionId: nil, exceptionMessage: nil, outputStream: outputStream) diff --git a/swift/src/Ice/PropertiesI.swift b/swift/src/Ice/PropertiesI.swift index f11f476dc37..7861783b7c0 100644 --- a/swift/src/Ice/PropertiesI.swift +++ b/swift/src/Ice/PropertiesI.swift @@ -8,10 +8,7 @@ class PropertiesI: LocalObject, Properties { } public func getIceProperty(_ key: String) throws -> String { - guard let value = handle.getIceProperty(key) else { - throw RuntimeError("unknown Ice property: \(key)") - } - return value + try handle.getIceProperty(key) } public func getPropertyWithDefault(key: String, value: String) -> String { @@ -23,10 +20,7 @@ class PropertiesI: LocalObject, Properties { } public func getIcePropertyAsInt(_ key: String) throws -> Int32 { - guard let value = handle.getIcePropertyAsInt(key) as? Int32 else { - throw RuntimeError("unknown Ice property: \(key)") - } - return value + try handle.getIcePropertyAsInt(key) as! Int32 } public func getPropertyAsIntWithDefault(key: String, value: Int32) -> Int32 { @@ -38,10 +32,7 @@ class PropertiesI: LocalObject, Properties { } public func getIcePropertyAsList(_ key: String) throws -> StringSeq { - guard let value = handle.getIcePropertyAsList(key) else { - throw RuntimeError("unknown Ice property: \(key)") - } - return value + try handle.getIcePropertyAsList(key) } public func getPropertyAsListWithDefault(key: String, value: StringSeq) -> StringSeq { diff --git a/swift/src/Ice/Proxy.swift b/swift/src/Ice/Proxy.swift index 406a5606ed8..ddfcd858914 100644 --- a/swift/src/Ice/Proxy.swift +++ b/swift/src/Ice/Proxy.swift @@ -1425,7 +1425,7 @@ open class ObjectPrxI: ObjectPrx { if let userException = userException { try userException(error) } - throw UnknownUserException(unknown: error.ice_id()) + throw UnknownUserException(badTypeId: error.ice_id()) } fatalError("Failed to throw user exception") } diff --git a/swift/src/Ice/ToStringMode.swift b/swift/src/Ice/ToStringMode.swift index ad2ef51c179..59f98c69dd8 100644 --- a/swift/src/Ice/ToStringMode.swift +++ b/swift/src/Ice/ToStringMode.swift @@ -32,7 +32,7 @@ extension InputStream { public func read() throws -> ToStringMode { let rawValue: UInt8 = try read(enumMaxValue: 2) guard let val = ToStringMode(rawValue: rawValue) else { - throw MarshalException(reason: "invalid enum value") + throw MarshalException("invalid enum value") } return val } diff --git a/swift/src/Ice/UserException.swift b/swift/src/Ice/UserException.swift new file mode 100644 index 00000000000..77f0bd1c957 --- /dev/null +++ b/swift/src/Ice/UserException.swift @@ -0,0 +1,33 @@ +// Copyright (c) ZeroC, Inc. + +/// Base class for Ice user exceptions. +open class UserException: Exception { + /// Gets the type ID of the class. + /// - Returns: The type ID of the class. + open class func ice_staticId() -> String { "::Ice::UserException" } + + public required init() {} + + open func _iceReadImpl(from _: InputStream) throws {} + open func _iceWriteImpl(to _: OutputStream) {} + + open func _usesClasses() -> Bool { false } + + open func _iceRead(from istr: InputStream) throws { + istr.startException() + try _iceReadImpl(from: istr) + try istr.endException() + } + + open func _iceWrite(to ostr: OutputStream) { + ostr.startException() + _iceWriteImpl(to: ostr) + ostr.endException() + } +} + +extension UserException { + /// Gets the type ID of this Ice user exception. + /// - Returns: The type ID of this Ice user exception. + public func ice_id() -> String { type(of: self).ice_staticId() } +} diff --git a/swift/src/Ice/Util.swift b/swift/src/Ice/Util.swift index c6a040109a3..aa6e0449222 100644 --- a/swift/src/Ice/Util.swift +++ b/swift/src/Ice/Util.swift @@ -16,11 +16,11 @@ func stringToEncodingVersion(_ s: String) throws -> EncodingVersion { func stringToMajorMinor(_ s: String) throws -> (UInt8, UInt8) { let components = s.components(separatedBy: ".") guard components.count == 2 else { - throw ParseException(str: "malformed Ice version string '\(s)'") + throw ParseException("malformed Ice version string '\(s)'") } guard let major = UInt8(components[0] as String), let minor = UInt8(components[1]) else { - throw ParseException(str: "invalid Ice version value '\(s)'") + throw ParseException("invalid Ice version value '\(s)'") } return (major, minor) @@ -79,6 +79,6 @@ func checkSupportedEncoding(_ v: EncodingVersion) throws { let c = currentEncoding if v.major != c.major || v.minor > c.minor { throw MarshalException( - reason: "this Ice runtime does not support encoding version \(encodingVersionToString(v))") + "this Ice runtime does not support encoding version \(encodingVersionToString(v))") } } diff --git a/swift/src/Ice/ValueFactoryManagerI.swift b/swift/src/Ice/ValueFactoryManagerI.swift index d2bd6eba87a..3b6b4be7dce 100644 --- a/swift/src/Ice/ValueFactoryManagerI.swift +++ b/swift/src/Ice/ValueFactoryManagerI.swift @@ -7,8 +7,7 @@ class ValueFactoryManagerI: ValueFactoryManager { func add(factory: @escaping ValueFactory, id: String) throws { try mutex.sync { if factories[id] != nil { - throw AlreadyRegisteredException( - kindOfObject: "value factory", id: id, file: #file, line: #line) + throw AlreadyRegisteredException(kindOfObject: "value factory", id: id) } factories[id] = factory } diff --git a/swift/src/IceImpl/Convert.h b/swift/src/IceImpl/Convert.h index 36f42b0e356..3fb51ccf1ca 100644 --- a/swift/src/IceImpl/Convert.h +++ b/swift/src/IceImpl/Convert.h @@ -14,6 +14,12 @@ toNSString(const std::string& s) return [[NSString alloc] initWithUTF8String:s.c_str()]; } +inline NSString* +toNSString(const char* s) +{ + return [[NSString alloc] initWithUTF8String:s]; +} + inline std::string fromNSString(NSString* s) { diff --git a/swift/src/IceImpl/Convert.mm b/swift/src/IceImpl/Convert.mm index 07794f2e7d6..2358cc2c24e 100644 --- a/swift/src/IceImpl/Convert.mm +++ b/swift/src/IceImpl/Convert.mm @@ -1,212 +1,103 @@ // Copyright (c) ZeroC, Inc. #import "Convert.h" -#import "Exception.h" #import "IceUtil.h" +#import "LocalExceptionFactory.h" + +#include +#include +#include +#include + +namespace +{ + inline std::string cxxDescription(const Ice::LocalException& e) + { + std::ostringstream os; + os << e; + return os.str(); + } +} NSError* convertException(std::exception_ptr exc) { assert(exc); - Class factory = [ICEUtil exceptionFactory]; + Class factory = [ICEUtil localExceptionFactory]; try { rethrow_exception(exc); } - catch (const Ice::InitializationException& e) - { - return [factory initializationException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::PluginInitializationException& e) - { - return [factory pluginInitializationException:toNSString(e.reason) - file:toNSString(e.ice_file()) - line:e.ice_line()]; - } - catch (const Ice::AlreadyRegisteredException& e) - { - return [factory alreadyRegisteredException:toNSString(e.kindOfObject) - id:toNSString(e.id) - file:toNSString(e.ice_file()) - line:e.ice_line()]; - } - catch (const Ice::NotRegisteredException& e) - { - return [factory notRegisteredException:toNSString(e.kindOfObject) - id:toNSString(e.id) - file:toNSString(e.ice_file()) - line:e.ice_line()]; - } - catch (const Ice::TwowayOnlyException& e) - { - return [factory twowayOnlyException:toNSString(e.operation) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::CommunicatorDestroyedException& e) - { - return [factory communicatorDestroyedException:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::ObjectAdapterDeactivatedException& e) - { - return [factory objectAdapterDeactivatedException:toNSString(e.name) - file:toNSString(e.ice_file()) - line:e.ice_line()]; - } - catch (const Ice::ObjectAdapterIdInUseException& e) - { - return [factory objectAdapterIdInUseException:toNSString(e.id) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::NoEndpointException& e) - { - return [factory noEndpointException:toNSString(e.proxy) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::ParseException& e) - { - return [factory parseException:toNSString(e.what()) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::IllegalIdentityException& e) - { - return [factory illegalIdentityException:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::IllegalServantException& e) - { - return [factory illegalServantException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::DNSException& e) - { - return [factory dNSException:e.error host:toNSString(e.host) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::InvocationCanceledException& e) - { - return [factory invocationCanceledException:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::FeatureNotSupportedException& e) - { - return [factory featureNotSupportedException:toNSString(e.what()) - file:toNSString(e.ice_file()) - line:e.ice_line()]; - } - catch (const Ice::FixedProxyException& e) - { - return [factory fixedProxyException:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::SecurityException& e) + catch (const Ice::RequestFailedException& e) { - return [factory securityException:toNSString(e.reason) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::UnknownLocalException& e) - { - return [factory unknownLocalException:toNSString(e.what()) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::UnknownUserException& e) - { - return [factory unknownUserException:toNSString(e.what()) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::UnknownException& e) - { - return [factory unknownException:toNSString(e.what()) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::ObjectNotExistException& e) - { - return [factory objectNotExistException:toNSString(e.id().name) - category:toNSString(e.id().category) - facet:toNSString(e.facet()) - operation:toNSString(e.operation()) - file:toNSString(e.ice_file()) - line:e.ice_line()]; - } - catch (const Ice::FacetNotExistException& e) - { - return [factory facetNotExistException:toNSString(e.id().name) + return [factory requestFailedException:toNSString(e.ice_id()) + name:toNSString(e.id().name) category:toNSString(e.id().category) facet:toNSString(e.facet()) operation:toNSString(e.operation()) + message:toNSString(e.what()) + cxxDescription:toNSString(cxxDescription(e)) file:toNSString(e.ice_file()) line:e.ice_line()]; } - catch (const Ice::OperationNotExistException& e) - { - return [factory operationNotExistException:toNSString(e.id().name) - category:toNSString(e.id().category) - facet:toNSString(e.facet()) - operation:toNSString(e.operation()) - file:toNSString(e.ice_file()) - line:e.ice_line()]; - } - catch (const Ice::ConnectionRefusedException& e) - { - return [factory connectionRefusedException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::FileException& e) - { - return [factory fileException:e.error path:toNSString(e.path) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::ConnectFailedException& e) - { - return [factory connectFailedException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::ConnectionLostException& e) - { - return [factory connectionLostException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::SocketException& e) - { - return [factory socketException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::SyscallException& e) - { - return [factory syscallException:e.error file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::ConnectTimeoutException& e) - { - return [factory connectTimeoutException:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::CloseTimeoutException& e) - { - return [factory closeTimeoutException:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::ConnectionIdleException& e) - { - return [factory connectionIdleException:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::InvocationTimeoutException& e) - { - return [factory invocationTimeoutException:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::TimeoutException& e) + catch (const Ice::AlreadyRegisteredException& e) { - return [factory timeoutException:toNSString(e.ice_file()) line:e.ice_line()]; + return [factory registeredException:toNSString(e.ice_id()) + kindOfObject:toNSString(e.kindOfObject) + objectId:toNSString(e.id) + message:toNSString(e.what()) + cxxDescription:toNSString(cxxDescription(e)) + file:toNSString(e.ice_file()) + line:e.ice_line()]; } - catch (const Ice::CloseConnectionException& e) + catch (const Ice::NotRegisteredException& e) { - return [factory closeConnectionException:toNSString(e.what()) file:toNSString(e.ice_file()) line:e.ice_line()]; + return [factory registeredException:toNSString(e.ice_id()) + kindOfObject:toNSString(e.kindOfObject) + objectId:toNSString(e.id) + message:toNSString(e.what()) + cxxDescription:toNSString(cxxDescription(e)) + file:toNSString(e.ice_file()) + line:e.ice_line()]; } catch (const Ice::ConnectionManuallyClosedException& e) { - return [factory connectionManuallyClosedException:e.graceful file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::DatagramLimitException& e) - { - return [factory datagramLimitException:toNSString(e.what()) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::MarshalException& e) - { - return [factory marshalException:toNSString(e.what()) file:toNSString(e.ice_file()) line:e.ice_line()]; - } - catch (const Ice::ProtocolException& e) - { - return [factory protocolException:toNSString(e.what()) file:toNSString(e.ice_file()) line:e.ice_line()]; + return [factory connectionManuallyClosedException:e.graceful + message:toNSString(e.what()) + cxxDescription:toNSString(cxxDescription(e)) + file:toNSString(e.ice_file()) + line:e.ice_line()]; } catch (const Ice::LocalException& e) { - return [factory localException:toNSString(e.ice_file()) line:e.ice_line()]; + return [factory localException:toNSString(e.ice_id()) + message:toNSString(e.what()) + cxxDescription:toNSString(cxxDescription(e)) + file:toNSString(e.ice_file()) + line:e.ice_line()]; } catch (const std::exception& e) { - return [factory runtimeError:toNSString(e.what())]; + int status = 0; + const char* mangled = typeid(e).name(); + char* demangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status); + + NSError* error = nullptr; + if (status == 0) // success + { + error = [factory cxxException:toNSString(demangled) message:toNSString(e.what())]; + std::free(demangled); + } + else + { + error = [factory cxxException:toNSString(mangled) message:toNSString(e.what())]; + assert(demangled == nullptr); + } + return error; } catch (...) { - return [factory runtimeError:toNSString("unknown c++ exception")]; + return [factory cxxException:toNSString("unknown C++ exception") message:toNSString("(no message)")]; } } diff --git a/swift/src/IceImpl/DispatchAdapter.mm b/swift/src/IceImpl/DispatchAdapter.mm index ce8826ef9ab..9033c0f333a 100644 --- a/swift/src/IceImpl/DispatchAdapter.mm +++ b/swift/src/IceImpl/DispatchAdapter.mm @@ -2,8 +2,8 @@ #import "DispatchAdapter.h" #import "Connection.h" #import "Convert.h" -#import "Exception.h" #import "Ice/AsyncResponseHandler.h" +#import "LocalExceptionFactory.h" #import "ObjectAdapter.h" void diff --git a/swift/src/IceImpl/Exception.h b/swift/src/IceImpl/Exception.h deleted file mode 100644 index b6634f6b51a..00000000000 --- a/swift/src/IceImpl/Exception.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) ZeroC, Inc. -#import "Config.h" -#import - -NS_ASSUME_NONNULL_BEGIN - -ICEIMPL_API @protocol ICEExceptionFactory -+ (NSError*)initializationException:(NSString*)reason file:(NSString*)file line:(int32_t)line; -+ (NSError*)pluginInitializationException:(NSString*)reason file:(NSString*)file line:(int32_t)line; -+ (NSError*)alreadyRegisteredException:(NSString*)kindOfObject id:(NSString*)id file:(NSString*)file line:(int32_t)line; -+ (NSError*)notRegisteredException:(NSString*)kindOfObject id:(NSString*)id file:(NSString*)file line:(int32_t)line; -+ (NSError*)twowayOnlyException:(NSString*)operation file:(NSString*)file line:(int32_t)line; -+ (NSError*)communicatorDestroyedException:(NSString*)file line:(int32_t)line; -+ (NSError*)objectAdapterDeactivatedException:(NSString*)name file:(NSString*)file line:(int32_t)line; -+ (NSError*)objectAdapterIdInUseException:(NSString*)id - file:(NSString*)file - line:(int32_t)line NS_SWIFT_NAME(objectAdapterIdInUseException(_:file:line:)); -+ (NSError*)noEndpointException:(NSString*)proxy file:(NSString*)file line:(int32_t)line; -+ (NSError*)parseException:(NSString*)str file:(NSString*)file line:(int32_t)line; -+ (NSError*)illegalIdentityException:(NSString*)file line:(int32_t)line; -+ (NSError*)illegalServantException:(NSString*)reason file:(NSString*)file line:(int32_t)line; -+ (NSError*)dNSException:(int32_t)error host:(NSString*)host file:(NSString*)file line:(int32_t)line; -+ (NSError*)invocationCanceledException:(NSString*)file line:(int32_t)line; -+ (NSError*)featureNotSupportedException:(NSString*)unsupportedFeature file:(NSString*)file line:(int32_t)line; -+ (NSError*)fixedProxyException:(NSString*)file line:(int32_t)line; -+ (NSError*)securityException:(NSString*)reason file:(NSString*)file line:(int32_t)line; -+ (NSError*)localException:(NSString*)file line:(int32_t)line; - -// UnknownException -+ (NSError*)unknownLocalException:(NSString*)unknown file:(NSString*)file line:(int32_t)line; -+ (NSError*)unknownUserException:(NSString*)unknown file:(NSString*)file line:(int32_t)line; -+ (NSError*)unknownException:(NSString*)unknown file:(NSString*)file line:(int32_t)line; - -// RequestFailedException -+ (NSError*)objectNotExistException:(NSString*)name - category:(NSString*)category - facet:(NSString*)facet - operation:(NSString*)operation - file:(NSString*)file - line:(int32_t)line; -+ (NSError*)facetNotExistException:(NSString*)name - category:(NSString*)category - facet:(NSString*)facet - operation:(NSString*)operation - file:(NSString*)file - line:(int32_t)line; -+ (NSError*)operationNotExistException:(NSString*)name - category:(NSString*)category - facet:(NSString*)facet - operation:(NSString*)operation - file:(NSString*)file - line:(int32_t)line; -+ (NSError*)requestFailedException:(NSString*)name - category:(NSString*)category - facet:(NSString*)facet - operation:(NSString*)operation - file:(NSString*)file - line:(int32_t)line; - -// SyscallException -+ (NSError*)connectionRefusedException:(int32_t)error - file:(NSString*)file - line:(int32_t)line; // ConnectFailedException: SyscallException -+ (NSError*)fileException:(int32_t)error path:(NSString*)path file:(NSString*)file line:(int32_t)line; -+ (NSError*)connectFailedException:(int32_t)error file:(NSString*)file line:(int32_t)line; -+ (NSError*)connectionLostException:(int32_t)error file:(NSString*)file line:(int32_t)line; -+ (NSError*)socketException:(int32_t)error file:(NSString*)file line:(int32_t)line; -+ (NSError*)syscallException:(int32_t)error file:(NSString*)file line:(int32_t)line; - -// ConnectionIdleException -+ (NSError*)connectionIdleException:(NSString*)file line:(int32_t)line; - -// TimeoutException -+ (NSError*)connectTimeoutException:(NSString*)file line:(int32_t)line; -+ (NSError*)closeTimeoutException:(NSString*)file line:(int32_t)line; -+ (NSError*)invocationTimeoutException:(NSString*)file line:(int32_t)line; -+ (NSError*)timeoutException:(NSString*)file line:(int32_t)line; - -// ProtocolException -+ (NSError*)closeConnectionException:(NSString*)reason file:(NSString*)file line:(int32_t)line; -+ (NSError*)connectionManuallyClosedException:(BOOL)graceful - file:(NSString*)file - line:(int32_t)line; // not a protocol exception -+ (NSError*)datagramLimitException:(NSString*)reason file:(NSString*)file line:(int32_t)line; -// ProtocolException/MarshalException -+ (NSError*)marshalException:(NSString*)reason file:(NSString*)file line:(int32_t)line; -+ (NSError*)protocolException:(NSString*)reason file:(NSString*)file line:(int32_t)line; - -// For generic std::exception -+ (NSError*)runtimeError:(NSString*)message; -@end - -NS_ASSUME_NONNULL_END diff --git a/swift/src/IceImpl/IceImpl.h b/swift/src/IceImpl/IceImpl.h index 8543bdf82ef..f90fe552eb3 100644 --- a/swift/src/IceImpl/IceImpl.h +++ b/swift/src/IceImpl/IceImpl.h @@ -4,9 +4,9 @@ #import "Connection.h" #import "DispatchAdapter.h" #import "Endpoint.h" -#import "Exception.h" #import "IceUtil.h" #import "ImplicitContext.h" +#import "LocalExceptionFactory.h" #import "LocalObject.h" #import "Logger.h" #import "ObjectAdapter.h" diff --git a/swift/src/IceImpl/IceUtil.h b/swift/src/IceImpl/IceUtil.h index cf15925be31..98bc2fd32f6 100644 --- a/swift/src/IceImpl/IceUtil.h +++ b/swift/src/IceImpl/IceUtil.h @@ -3,7 +3,7 @@ #import "Communicator.h" #import "Connection.h" #import "Endpoint.h" -#import "Exception.h" +#import "LocalExceptionFactory.h" #import "Logger.h" #import "Properties.h" @@ -13,13 +13,13 @@ NS_ASSUME_NONNULL_BEGIN // Utility methods // ICEIMPL_API @interface ICEUtil : NSObject -@property(class, nonatomic, readonly) Class exceptionFactory; +@property(class, nonatomic, readonly) Class localExceptionFactory; @property(class, nonatomic, readonly) Class connectionInfoFactory; @property(class, nonatomic, readonly) Class endpointInfoFactory; @property(class, nonatomic, readonly) Class adminFacetFactory; // This method should only be called once to guarenteed thread safety -+ (BOOL)registerFactories:(Class)exception ++ (BOOL)registerFactories:(Class)exception connectionInfo:(Class)connectionInfo endpointInfo:(Class)endpointInfo adminFacet:(Class)adminFacet diff --git a/swift/src/IceImpl/IceUtil.mm b/swift/src/IceImpl/IceUtil.mm index 801e2974e09..dbdb97fef96 100644 --- a/swift/src/IceImpl/IceUtil.mm +++ b/swift/src/IceImpl/IceUtil.mm @@ -31,12 +31,12 @@ } @implementation ICEUtil -static Class _exceptionFactory; +static Class _exceptionFactory; static Class _connectionInfoFactory; static Class _endpointInfoFactory; static Class _adminFacetFactory; -+ (Class)exceptionFactory ++ (Class)localExceptionFactory { return _exceptionFactory; } @@ -56,7 +56,7 @@ @implementation ICEUtil return _adminFacetFactory; } -+ (BOOL)registerFactories:(Class)exception ++ (BOOL)registerFactories:(Class)exception connectionInfo:(Class)connectionInfo endpointInfo:(Class)endpointInfo adminFacet:(Class)adminFacet diff --git a/swift/src/IceImpl/LocalExceptionFactory.h b/swift/src/IceImpl/LocalExceptionFactory.h new file mode 100644 index 00000000000..530cb0fe5ea --- /dev/null +++ b/swift/src/IceImpl/LocalExceptionFactory.h @@ -0,0 +1,48 @@ +// Copyright (c) ZeroC, Inc. +#import "Config.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +ICEIMPL_API @protocol ICELocalExceptionFactory + +// Local exceptions with the same fields share a factory method. + +// The 3 NoExist exceptions. ++ (NSError*)requestFailedException:(NSString*)typeId + name:(NSString*)name + category:(NSString*)category + facet:(NSString*)facet + operation:(NSString*)operation + message:(NSString*)message + cxxDescription:(NSString*)cxxDescription + file:(NSString*)file + line:(int32_t)line; + +// AlreadyRegisteredException + NotRegisteredException ++ (NSError*)registeredException:(NSString*)typeId + kindOfObject:(NSString*)kindOfObject + objectId:(NSString*)objectId + message:(NSString*)message + cxxDescription:(NSString*)cxxDescription + file:(NSString*)file + line:(int32_t)line; +// Temporary ++ (NSError*)connectionManuallyClosedException:(BOOL)graceful + message:(NSString*)message + cxxDescription:(NSString*)cxxDescription + file:(NSString*)file + line:(int32_t)line; + +// All other local exceptions. ++ (NSError*)localException:(NSString*)typeId + message:(NSString*)message + cxxDescription:(NSString*)cxxDescription + file:(NSString*)file + line:(int32_t)line; + +// Other std::exception ++ (NSError*)cxxException:(NSString*)typeName message:(NSString*)message; +@end + +NS_ASSUME_NONNULL_END diff --git a/swift/src/IceImpl/Properties.h b/swift/src/IceImpl/Properties.h index 5c7fe19706a..0b6afe8badc 100644 --- a/swift/src/IceImpl/Properties.h +++ b/swift/src/IceImpl/Properties.h @@ -5,14 +5,15 @@ NS_ASSUME_NONNULL_BEGIN ICEIMPL_API @interface ICEProperties : ICELocalObject - (nonnull NSString*)getProperty:(NSString*)key; -- (nullable NSString*)getIceProperty:(NSString*)key NS_SWIFT_NAME(getIceProperty(_:)); +- (nullable NSString*)getIceProperty:(NSString*)key error:(NSError**)error NS_SWIFT_NAME(getIceProperty(_:)); - (nonnull NSString*)getPropertyWithDefault:(NSString*)key value:(NSString*)value; - (int32_t)getPropertyAsInt:(NSString*)key; -- (nullable id)getIcePropertyAsInt:(NSString*)key NS_SWIFT_NAME(getIcePropertyAsInt(_:)); +- (nullable NSNumber*)getIcePropertyAsInt:(NSString*)key error:(NSError**)error NS_SWIFT_NAME(getIcePropertyAsInt(_:)); - (int32_t)getPropertyAsIntWithDefault:(NSString*)key value:(int32_t)value NS_SWIFT_NAME(getPropertyAsIntWithDefault(key:value:)); - (nonnull NSArray*)getPropertyAsList:(NSString* _Nonnull)key; -- (nullable NSArray*)getIcePropertyAsList:(NSString* _Nonnull)key NS_SWIFT_NAME(getIcePropertyAsList(_:)); +- (nullable NSArray*)getIcePropertyAsList:(NSString* _Nonnull)key + error:(NSError**)error NS_SWIFT_NAME(getIcePropertyAsList(_:)); - (nonnull NSArray*)getPropertyAsListWithDefault:(NSString* _Nonnull)key value:(NSArray* _Nonnull)value NS_SWIFT_NAME(getPropertyAsListWithDefault(key:value:)); diff --git a/swift/src/IceImpl/Properties.mm b/swift/src/IceImpl/Properties.mm index 6bd29b30bfc..e44718a0fa9 100644 --- a/swift/src/IceImpl/Properties.mm +++ b/swift/src/IceImpl/Properties.mm @@ -15,17 +15,17 @@ - (NSString*)getProperty:(NSString*)key return toNSString(self.properties->getProperty(fromNSString(key))); } -- (NSString*)getIceProperty:(NSString*)key +- (NSString*)getIceProperty:(NSString*)key error:(NSError**)error; { try { - toNSString(self.properties->getIceProperty(fromNSString(key))); + return toNSString(self.properties->getIceProperty(fromNSString(key))); } - catch (const std::invalid_argument&) + catch (...) { + *error = convertException(std::current_exception()); return nil; } - return toNSString(self.properties->getIceProperty(fromNSString(key))); } - (NSString*)getPropertyWithDefault:(NSString*)key value:(NSString*)value @@ -38,15 +38,16 @@ - (int32_t)getPropertyAsInt:(NSString*)key return self.properties->getPropertyAsInt(fromNSString(key)); } -- (id)getIcePropertyAsInt:(NSString*)key +- (NSNumber*)getIcePropertyAsInt:(NSString*)key error:(NSError**)error { try { int32_t value = self.properties->getIcePropertyAsInt(fromNSString(key)); return [NSNumber numberWithInt:value]; } - catch (const std::invalid_argument&) + catch (...) { + *error = convertException(std::current_exception()); return nil; } } @@ -61,9 +62,17 @@ - (int32_t)getPropertyAsIntWithDefault:(NSString*)key value:(int32_t)value return toNSArray(self.properties->getPropertyAsList(fromNSString(key))); } -- (NSArray*)getIcePropertyAsList:(NSString*)key +- (NSArray*)getIcePropertyAsList:(NSString*)key error:(NSError**)error { - return toNSArray(self.properties->getIcePropertyAsList(fromNSString(key))); + try + { + return toNSArray(self.properties->getIcePropertyAsList(fromNSString(key))); + } + catch (...) + { + *error = convertException(std::current_exception()); + return nil; + } } - (NSArray*)getPropertyAsListWithDefault:(NSString*)key value:(NSArray*)value diff --git a/swift/test/Ice/adapterDeactivation/AllTests.swift b/swift/test/Ice/adapterDeactivation/AllTests.swift index c1417b3fd64..dcd2a5c4fc0 100644 --- a/swift/test/Ice/adapterDeactivation/AllTests.swift +++ b/swift/test/Ice/adapterDeactivation/AllTests.swift @@ -120,7 +120,10 @@ func allTests(_ helper: TestHelper) throws { do { try adapter.setPublishedEndpoints(router.ice_getEndpoints()) try test(false) - } catch is Ice.RuntimeError {} + } catch let error as Ice.LocalException { + try test(error.ice_id() == "std::invalid_argument") + try test(error.message == "can't set published endpoints on object adapter associated with a router") + } adapter.destroy() do { diff --git a/swift/test/Ice/exceptions/AllTests.swift b/swift/test/Ice/exceptions/AllTests.swift index a64f1d229d0..adc142d3936 100644 --- a/swift/test/Ice/exceptions/AllTests.swift +++ b/swift/test/Ice/exceptions/AllTests.swift @@ -14,6 +14,8 @@ class ServantLocatorI: Ice.ServantLocator { func deactivate(_: String) {} } +class CustomLocalException: LocalException {} + func allTests(_ helper: TestHelper) throws -> ThrowerPrx { func test(_ value: Bool, file: String = #file, line: Int = #line) throws { try helper.test(value, file: file, line: line) diff --git a/swift/test/Ice/exceptions/TestAMDI.swift b/swift/test/Ice/exceptions/TestAMDI.swift index 1a2ca89c0d1..edff69a6f1e 100644 --- a/swift/test/Ice/exceptions/TestAMDI.swift +++ b/swift/test/Ice/exceptions/TestAMDI.swift @@ -94,7 +94,7 @@ class ThrowerI: Thrower { func throwLocalExceptionAsync(current _: Current) -> Promise { return Promise { seal in - seal.reject(Ice.TimeoutException()) + seal.reject(Ice.TimeoutException("thrower throwing TimeOutException")) } } @@ -117,21 +117,21 @@ class ThrowerI: Thrower { func throwLocalExceptionIdempotentAsync(current _: Current) -> Promise { return Promise { seal in - seal.reject(Ice.TimeoutException()) + seal.reject(Ice.TimeoutException("thrower throwing TimeOutException")) } } func throwAfterResponseAsync(current _: Current) -> Promise { return Promise { seal in seal.fulfill(()) - throw Ice.RuntimeError("") + throw Ice.LocalException("after response") } } func throwAfterExceptionAsync(current _: Current) -> Promise { return Promise { seal in seal.reject(A(aMem: 12345)) - throw Ice.RuntimeError("") + throw Ice.LocalException("after exception") } } diff --git a/swift/test/Ice/exceptions/TestI.swift b/swift/test/Ice/exceptions/TestI.swift index 05ef0c7b18e..3ad3fe5dc9c 100644 --- a/swift/test/Ice/exceptions/TestI.swift +++ b/swift/test/Ice/exceptions/TestI.swift @@ -58,7 +58,7 @@ class ThrowerI: Thrower { } func throwLocalException(current _: Ice.Current) throws { - throw Ice.TimeoutException() + throw Ice.TimeoutException("thrower throwing TimeOutException") } func throwNonIceException(current _: Ice.Current) throws { @@ -73,7 +73,7 @@ class ThrowerI: Thrower { } func throwLocalExceptionIdempotent(current _: Ice.Current) throws { - throw Ice.TimeoutException() + throw Ice.TimeoutException("thrower throwing TimeOutException") } func throwUndeclaredA(a: Int32, current _: Ice.Current) throws { diff --git a/swift/test/Ice/objects/AllTests.swift b/swift/test/Ice/objects/AllTests.swift index d137618abc8..635a301f815 100644 --- a/swift/test/Ice/objects/AllTests.swift +++ b/swift/test/Ice/objects/AllTests.swift @@ -247,8 +247,8 @@ func allTests(_ helper: TestHelper) throws -> InitialPrx { _ = try uoet.op() try test(false) } catch let ex as Ice.MarshalException { - try test(ex.reason.contains("::Test::AlsoEmpty")) - try test(ex.reason.contains("::Test::Empty")) + try test(ex.message.contains("::Test::AlsoEmpty")) + try test(ex.message.contains("::Test::Empty")) } catch { output.writeLine("\(error)") try test(false) diff --git a/swift/test/Ice/properties/Client.swift b/swift/test/Ice/properties/Client.swift index f21739d54b2..f147d7a1571 100644 --- a/swift/test/Ice/properties/Client.swift +++ b/swift/test/Ice/properties/Client.swift @@ -12,8 +12,9 @@ public class Client: TestHelperI { let properties = Ice.createProperties() try properties.load("./config/xxxx.config") try test(false) - } catch is FileException { - // Expected when try to load a non existing config file + } catch let error as LocalException { + // We don't map FileException to Swift - this allows us to test unmapped C++ exceptions. + try test(error.ice_id() == "::Ice::FileException") } output.writeLine("ok") @@ -135,8 +136,9 @@ public class Client: TestHelperI { do { _ = try properties.getIceProperty("Ice.UnknownProperty") try test(false) - } catch let error as RuntimeError { - try test(error.description == "unknown Ice property: Ice.UnknownProperty") + } catch let error as LocalException { + try test(error.ice_id() == "std::invalid_argument") + try test(error.message == "unknown Ice property: Ice.UnknownProperty") } output.write("ok") diff --git a/swift/test/Ice/proxy/AllTests.swift b/swift/test/Ice/proxy/AllTests.swift index 7ba9cc53736..9b601813fc4 100644 --- a/swift/test/Ice/proxy/AllTests.swift +++ b/swift/test/Ice/proxy/AllTests.swift @@ -745,8 +745,8 @@ public func allTests(_ helper: TestHelper) throws -> MyClassPrx { } catch let ex as Ice.UnknownLocalException { // TODO: remove UnsupportedEncodingException try test( - ex.unknown.contains("::Ice::MarshalException") || ex.unknown.contains("Ice.MarshalException") - || ex.unknown.contains("UnsupportedEncodingException")) + ex.message.contains("::Ice::MarshalException") || ex.message.contains("Ice.MarshalException") + || ex.message.contains("UnsupportedEncodingException")) } do { @@ -763,8 +763,8 @@ public func allTests(_ helper: TestHelper) throws -> MyClassPrx { } catch let ex as Ice.UnknownLocalException { // TODO: remove UnsupportedEncodingException try test( - ex.unknown.contains("::Ice::MarshalException") || ex.unknown.contains("Ice.MarshalException") - || ex.unknown.contains("UnsupportedEncodingException")) + ex.message.contains("::Ice::MarshalException") || ex.message.contains("Ice.MarshalException") + || ex.message.contains("UnsupportedEncodingException")) } writer.writeLine("ok") diff --git a/swift/test/Ice/retry/TestI.swift b/swift/test/Ice/retry/TestI.swift index ee4d493e356..6adacebe1de 100644 --- a/swift/test/Ice/retry/TestI.swift +++ b/swift/test/Ice/retry/TestI.swift @@ -15,7 +15,7 @@ class RetryI: Retry { if let con = current.con { try con.close(.Forcefully) } else { - throw Ice.ConnectionLostException(error: 1) + throw Ice.ConnectionLostException("op failed") } } } @@ -27,7 +27,7 @@ class RetryI: Retry { } if c > _counter { _counter += 1 - throw Ice.ConnectionLostException(error: 1) + throw Ice.ConnectionLostException("opIdempotent failed") } let counter = _counter _counter = 0 @@ -35,7 +35,7 @@ class RetryI: Retry { } func opNotIdempotent(current _: Ice.Current) throws { - throw Ice.ConnectionLostException(error: 1) + throw Ice.ConnectionLostException("opNotIdempotent failed") } func sleep(delay: Int32, current _: Ice.Current) throws { diff --git a/swift/test/Ice/servantLocator/AllTests.swift b/swift/test/Ice/servantLocator/AllTests.swift index 41ebaa0689c..27c49a34898 100644 --- a/swift/test/Ice/servantLocator/AllTests.swift +++ b/swift/test/Ice/servantLocator/AllTests.swift @@ -17,28 +17,28 @@ func testExceptions(_ obj: TestIntfPrx, _ helper: TestHelper) throws { try obj.unknownUserException() try helper.test(false) } catch let ex as Ice.UnknownUserException { - try helper.test(ex.unknown == "reason") + try helper.test(ex.message.contains("::Foo::BarException")) } do { try obj.unknownLocalException() try helper.test(false) } catch let ex as Ice.UnknownLocalException { - try helper.test(ex.unknown == "reason") + try helper.test(ex.message == "reason") } do { try obj.unknownException() try helper.test(false) } catch let ex as Ice.UnknownException { - try helper.test(ex.unknown == "reason") + try helper.test(ex.message == "reason") } do { try obj.userException() try helper.test(false) } catch let ex as Ice.UnknownUserException { - try helper.test(ex.unknown.contains("Test::TestIntfUserException")) + try helper.test(ex.message.contains("Test::TestIntfUserException")) } catch is Ice.OperationNotExistException {} do { @@ -46,14 +46,14 @@ func testExceptions(_ obj: TestIntfPrx, _ helper: TestHelper) throws { try helper.test(false) } catch let ex as Ice.UnknownLocalException { try helper.test( - ex.unknown.contains("Ice::SocketException") || ex.unknown.contains("Ice.SocketException")) + ex.message.contains("Ice::SocketException") || ex.message.contains("Ice.SocketException")) } do { try obj.unknownExceptionWithServantException() try helper.test(false) } catch let ex as Ice.UnknownException { - try helper.test(ex.unknown == "reason") + try helper.test(ex.message == "reason") } do { @@ -108,7 +108,7 @@ func allTests(_ helper: TestHelper) throws -> TestIntfPrx { _ = try o.ice_ids() try test(false) } catch let ex as Ice.UnknownUserException { - try test(ex.unknown == "::Test::TestIntfUserException") + try test(ex.message.contains("::Test::TestIntfUserException")) } do { @@ -116,7 +116,7 @@ func allTests(_ helper: TestHelper) throws -> TestIntfPrx { _ = try o.ice_ids() try test(false) } catch let ex as Ice.UnknownUserException { - try test(ex.unknown == "::Test::TestIntfUserException") + try test(ex.message.contains("::Test::TestIntfUserException")) } output.writeLine("ok") diff --git a/swift/test/Ice/servantLocator/ServantLocatorI.swift b/swift/test/Ice/servantLocator/ServantLocatorI.swift index 2bf9e46dd47..4d3ec06cff4 100644 --- a/swift/test/Ice/servantLocator/ServantLocatorI.swift +++ b/swift/test/Ice/servantLocator/ServantLocatorI.swift @@ -95,17 +95,17 @@ class ServantLocatorI: Ice.ServantLocator { throw Ice.ObjectNotExistException( id: current.id, facet: current.facet, operation: current.operation) } else if current.operation == "unknownUserException" { - throw Ice.UnknownUserException(unknown: "reason") + throw Ice.UnknownUserException(badTypeId: "::Foo::BarException") } else if current.operation == "unknownLocalException" { - throw Ice.UnknownLocalException(unknown: "reason") + throw Ice.UnknownLocalException("reason") } else if current.operation == "unknownException" { - throw Ice.UnknownException(unknown: "reason") + throw Ice.UnknownException("reason") } else if current.operation == "userException" { throw TestIntfUserException() } else if current.operation == "localException" { - throw Ice.SocketException(error: 0) + throw Ice.SocketException("socket error") } else if current.operation == "unknownExceptionWithServantException" { - throw Ice.UnknownException(unknown: "reason") + throw Ice.UnknownException("reason") } else if current.operation == "impossibleException" { throw TestIntfUserException() // Yes, it really is meant to be TestIntfException. } else if current.operation == "intfUserException" { diff --git a/swift/test/TestDriver/iOS/ControllerI.swift b/swift/test/TestDriver/iOS/ControllerI.swift index b582e29dcc8..571fb747c98 100644 --- a/swift/test/TestDriver/iOS/ControllerI.swift +++ b/swift/test/TestDriver/iOS/ControllerI.swift @@ -56,7 +56,7 @@ class ProcessControllerI: CommonProcessController { current: Ice.Current ) throws -> CommonProcessPrx? { guard let adapter = current.adapter else { - throw Ice.RuntimeError("Error") + throw Ice.LocalException("current.adapter is nil") } _view.println("starting \(testsuite) \(exe)... ")