]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | ||
20 | ||
21 | public struct TApplicationError : TError { | |
22 | public enum Code : TErrorCode { | |
23 | case unknown | |
24 | case unknownMethod(methodName: String?) | |
25 | case invalidMessageType | |
26 | case wrongMethodName(methodName: String?) | |
27 | case badSequenceId | |
28 | case missingResult(methodName: String?) | |
29 | case internalError | |
30 | case protocolError | |
31 | case invalidTransform | |
32 | case invalidProtocol | |
33 | case unsupportedClientType | |
34 | ||
35 | ||
36 | /// Initialize a TApplicationError with a Thrift error code | |
37 | /// Normally this would be achieved with RawRepresentable however | |
38 | /// by doing this we can allow for associated properties on enum cases for | |
39 | /// case specific context data in a Swifty, type-safe manner. | |
40 | /// | |
41 | /// - parameter thriftErrorCode: Integer TApplicationError(exception) error code. | |
42 | /// Default to 0 (.unknown) | |
43 | public init(thriftErrorCode: Int) { | |
44 | switch thriftErrorCode { | |
45 | case 1: self = .unknownMethod(methodName: nil) | |
46 | case 2: self = .invalidMessageType | |
47 | case 3: self = .wrongMethodName(methodName: nil) | |
48 | case 4: self = .badSequenceId | |
49 | case 5: self = .missingResult(methodName: nil) | |
50 | case 6: self = .internalError | |
51 | case 7: self = .protocolError | |
52 | case 8: self = .invalidProtocol | |
53 | case 9: self = .invalidTransform | |
54 | case 10: self = .unsupportedClientType | |
55 | default: self = .unknown | |
56 | } | |
57 | } | |
58 | public var thriftErrorCode: Int { | |
59 | switch self { | |
60 | case .unknown: return 0 | |
61 | case .unknownMethod: return 1 | |
62 | case .invalidMessageType: return 2 | |
63 | case .wrongMethodName: return 3 | |
64 | case .badSequenceId: return 4 | |
65 | case .missingResult: return 5 | |
66 | case .internalError: return 6 | |
67 | case .protocolError: return 7 | |
68 | case .invalidProtocol: return 8 | |
69 | case .invalidTransform: return 9 | |
70 | case .unsupportedClientType: return 10 | |
71 | } | |
72 | } | |
73 | ||
74 | public var description: String { | |
75 | /// Output "for #methodName" if method is not nil else empty | |
76 | let methodUnwrap: (String?) -> String = { method in | |
77 | return "\(method == nil ? "" : " for \(method ?? "")")" | |
78 | } | |
79 | switch self { | |
80 | case .unknown: return "Unknown TApplicationError" | |
81 | case .unknownMethod(let method): return "Unknown Method\(methodUnwrap(method))" | |
82 | case .invalidMessageType: return "Invalid Message Type" | |
83 | case .wrongMethodName(let method): return "Wrong Method Name\(methodUnwrap(method))" | |
84 | case .badSequenceId: return "Bad Sequence ID" | |
85 | case .missingResult(let method): return "Missing Result\(methodUnwrap(method))" | |
86 | case .internalError: return "Internal Error" | |
87 | case .protocolError: return "Protocol Error" | |
88 | case .invalidProtocol: return "Invalid Protocol" | |
89 | case .invalidTransform: return "Invalid Transform" | |
90 | case .unsupportedClientType: return "Unsupported Client Type" | |
91 | } | |
92 | } | |
93 | } | |
94 | ||
95 | public init() { } | |
96 | ||
97 | public init(thriftErrorCode code: Int, message: String? = nil) { | |
98 | self.error = Code(thriftErrorCode: code) | |
99 | self.message = message | |
100 | } | |
101 | ||
102 | public var error: Code = .unknown | |
103 | public var message: String? = nil | |
104 | public static var defaultCase: Code { return .unknown } | |
105 | } | |
106 | ||
107 | extension TApplicationError : TSerializable { | |
108 | public static var thriftType: TType { return .struct } | |
109 | ||
110 | public static func read(from proto: TProtocol) throws -> TApplicationError { | |
111 | var errorCode: Int = 0 | |
112 | var message: String? = nil | |
113 | _ = try proto.readStructBegin() | |
114 | fields: while true { | |
115 | let (_, fieldType, fieldID) = try proto.readFieldBegin() | |
116 | ||
117 | switch (fieldID, fieldType) { | |
118 | case (_, .stop): | |
119 | break fields | |
120 | case (1, .string): | |
121 | message = try proto.read() | |
122 | case (2, .i32): | |
123 | errorCode = Int(try proto.read() as Int32) | |
124 | ||
125 | case let (_, unknownType): | |
126 | try proto.skip(type: unknownType) | |
127 | } | |
128 | ||
129 | try proto.readFieldEnd() | |
130 | } | |
131 | try proto.readStructEnd() | |
132 | return TApplicationError(thriftErrorCode: errorCode, message: message) | |
133 | } | |
134 | ||
135 | public func write(to proto: TProtocol) throws { | |
136 | try proto.writeStructBegin(name: "TApplicationException") | |
137 | ||
138 | try proto.writeFieldBegin(name: "message", type: .string, fieldID: 1) | |
139 | try proto.write(message ?? "") | |
140 | try proto.writeFieldEnd() | |
141 | ||
142 | try proto.writeFieldBegin(name: "type", type: .i32, fieldID: 2) | |
143 | let val = Int32(error.thriftErrorCode) | |
144 | try proto.write(val) | |
145 | try proto.writeFieldEnd() | |
146 | try proto.writeFieldStop() | |
147 | try proto.writeStructEnd() | |
148 | } | |
149 | ||
150 | public var hashValue: Int { | |
151 | return error.thriftErrorCode &+ (message?.hashValue ?? 0) | |
152 | } | |
153 | } | |
154 | ||
155 | public func ==(lhs: TApplicationError, rhs: TApplicationError) -> Bool { | |
156 | return lhs.error.thriftErrorCode == rhs.error.thriftErrorCode && lhs.message == rhs.message | |
157 | } |