Skip to content

Commit e2a60d6

Browse files
Refactors erroring, exposes error codes
1 parent f1d0cd3 commit e2a60d6

File tree

4 files changed

+80
-65
lines changed

4 files changed

+80
-65
lines changed

Sources/GraphQLWS/Client.swift

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ public class Client {
2828
) {
2929
self.messenger = messenger
3030
messenger.onRecieve { message in
31-
guard let messenger = self.messenger else { return }
32-
3331
self.onMessage(message, self)
3432

3533
// Detect and ignore error responses.
@@ -39,8 +37,7 @@ public class Client {
3937
}
4038

4139
guard let json = message.data(using: .utf8) else {
42-
let error = GraphQLWSError.invalidEncoding()
43-
messenger.error(error.message, code: error.code)
40+
self.error(.invalidEncoding())
4441
return
4542
}
4643

@@ -49,57 +46,49 @@ public class Client {
4946
response = try self.decoder.decode(Response.self, from: json)
5047
}
5148
catch {
52-
let error = GraphQLWSError.noType()
53-
messenger.error(error.message, code: error.code)
49+
self.error(.noType())
5450
return
5551
}
5652

5753
switch response.type {
5854
case .GQL_CONNECTION_ERROR:
5955
guard let connectionErrorResponse = try? self.decoder.decode(ConnectionErrorResponse.self, from: json) else {
60-
let error = GraphQLWSError.invalidResponseFormat(messageType: .GQL_CONNECTION_ERROR)
61-
messenger.error(error.message, code: error.code)
56+
self.error(.invalidResponseFormat(messageType: .GQL_CONNECTION_ERROR))
6257
return
6358
}
6459
self.onConnectionError(connectionErrorResponse, self)
6560
case .GQL_CONNECTION_ACK:
6661
guard let connectionAckResponse = try? self.decoder.decode(ConnectionAckResponse.self, from: json) else {
67-
let error = GraphQLWSError.invalidResponseFormat(messageType: .GQL_CONNECTION_ACK)
68-
messenger.error(error.message, code: error.code)
62+
self.error(.invalidResponseFormat(messageType: .GQL_CONNECTION_ERROR))
6963
return
7064
}
7165
self.onConnectionAck(connectionAckResponse, self)
7266
case .GQL_CONNECTION_KEEP_ALIVE:
7367
guard let connectionKeepAliveResponse = try? self.decoder.decode(ConnectionKeepAliveResponse.self, from: json) else {
74-
let error = GraphQLWSError.invalidResponseFormat(messageType: .GQL_CONNECTION_KEEP_ALIVE)
75-
messenger.error(error.message, code: error.code)
68+
self.error(.invalidResponseFormat(messageType: .GQL_CONNECTION_KEEP_ALIVE))
7669
return
7770
}
7871
self.onConnectionKeepAlive(connectionKeepAliveResponse, self)
7972
case .GQL_DATA:
8073
guard let nextResponse = try? self.decoder.decode(DataResponse.self, from: json) else {
81-
let error = GraphQLWSError.invalidResponseFormat(messageType: .GQL_DATA)
82-
messenger.error(error.message, code: error.code)
74+
self.error(.invalidResponseFormat(messageType: .GQL_DATA))
8375
return
8476
}
8577
self.onData(nextResponse, self)
8678
case .GQL_ERROR:
8779
guard let errorResponse = try? self.decoder.decode(ErrorResponse.self, from: json) else {
88-
let error = GraphQLWSError.invalidResponseFormat(messageType: .GQL_ERROR)
89-
messenger.error(error.message, code: error.code)
80+
self.error(.invalidResponseFormat(messageType: .GQL_ERROR))
9081
return
9182
}
9283
self.onError(errorResponse, self)
9384
case .GQL_COMPLETE:
9485
guard let completeResponse = try? self.decoder.decode(CompleteResponse.self, from: json) else {
95-
let error = GraphQLWSError.invalidResponseFormat(messageType: .GQL_COMPLETE)
96-
messenger.error(error.message, code: error.code)
86+
self.error(.invalidResponseFormat(messageType: .GQL_COMPLETE))
9787
return
9888
}
9989
self.onComplete(completeResponse, self)
10090
case .unknown:
101-
let error = GraphQLWSError.invalidType()
102-
messenger.error(error.message, code: error.code)
91+
self.error(.invalidType())
10392
}
10493
}
10594
}
@@ -184,4 +173,10 @@ public class Client {
184173
ConnectionTerminateRequest().toJSON(encoder)
185174
)
186175
}
176+
177+
/// Send an error through the messenger and close the connection
178+
private func error(_ error: GraphQLWSError) {
179+
guard let messenger = messenger else { return }
180+
messenger.error(error.message, code: error.code.rawValue)
181+
}
187182
}

Sources/GraphQLWS/GraphQLWSError.swift

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,114 @@
22

33
struct GraphQLWSError: Error {
44
let message: String
5-
let code: Int
5+
let code: ErrorCode
66

7-
init(_ message: String, code: Int) {
7+
init(_ message: String, code: ErrorCode) {
88
self.message = message
99
self.code = code
1010
}
1111

1212
static func unauthorized() -> Self {
1313
return self.init(
1414
"Unauthorized",
15-
code: 4401
15+
code: .unauthorized
1616
)
1717
}
1818

19-
static func tooManyInitializations() -> Self {
19+
static func notInitialized() -> Self {
2020
return self.init(
21-
"Too many initialisation requests",
22-
code: 4429
21+
"Connection not initialized",
22+
code: .notInitialized
2323
)
2424
}
2525

26-
static func notInitialized() -> Self {
26+
static func tooManyInitializations() -> Self {
2727
return self.init(
28-
"Connection not initialized",
29-
code: 4407
28+
"Too many initialisation requests",
29+
code: .tooManyInitializations
3030
)
3131
}
3232

3333
static func subscriberAlreadyExists(id: String) -> Self {
3434
return self.init(
3535
"Subscriber for \(id) already exists",
36-
code: 4409
36+
code: .subscriberAlreadyExists
3737
)
3838
}
3939

4040
static func invalidEncoding() -> Self {
4141
return self.init(
4242
"Message was not encoded in UTF8",
43-
code: 4400
43+
code: .invalidEncoding
4444
)
4545
}
4646

4747
static func noType() -> Self {
4848
return self.init(
4949
"Message has no 'type' field",
50-
code: 4400
50+
code: .noType
5151
)
5252
}
5353

5454
static func invalidType() -> Self {
5555
return self.init(
5656
"Message 'type' value does not match supported types",
57-
code: 4400
57+
code: .invalidType
5858
)
5959
}
6060

6161
static func invalidRequestFormat(messageType: RequestMessageType) -> Self {
6262
return self.init(
6363
"Request message doesn't match '\(messageType.rawValue)' JSON format",
64-
code: 4400
64+
code: .invalidRequestFormat
6565
)
6666
}
6767

6868
static func invalidResponseFormat(messageType: ResponseMessageType) -> Self {
6969
return self.init(
7070
"Response message doesn't match '\(messageType.rawValue)' JSON format",
71-
code: 4400
71+
code: .invalidResponseFormat
7272
)
7373
}
7474

7575
static func internalAPIStreamIssue() -> Self {
7676
return self.init(
7777
"API Response did not result in a stream type",
78-
code: 4400
78+
code: .internalAPIStreamIssue
7979
)
8080
}
8181

8282
static func graphQLError(_ error: Error) -> Self {
8383
return self.init(
8484
"\(error)",
85-
code: 4400
85+
code: .graphQLError
8686
)
8787
}
8888
}
89+
90+
/// Error codes for miscellaneous issues
91+
public enum ErrorCode: Int, CustomStringConvertible {
92+
// Miscellaneous
93+
case miscellaneous = 4400
94+
95+
// Internal errors
96+
case graphQLError = 4401
97+
case internalAPIStreamIssue = 4402
98+
99+
// Message errors
100+
case invalidEncoding = 4410
101+
case noType = 4411
102+
case invalidType = 4412
103+
case invalidRequestFormat = 4413
104+
case invalidResponseFormat = 4414
105+
106+
// Initialization errors
107+
case unauthorized = 4430
108+
case notInitialized = 4431
109+
case tooManyInitializations = 4432
110+
case subscriberAlreadyExists = 4433
111+
112+
public var description: String {
113+
return "\(self.rawValue)"
114+
}
115+
}

Sources/GraphQLWS/Server.swift

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ public class Server {
5151
}
5252

5353
guard let json = message.data(using: .utf8) else {
54-
let error = GraphQLWSError.invalidEncoding()
55-
messenger.error(error.message, code: error.code)
54+
self.error(.invalidEncoding())
5655
return
5756
}
5857

@@ -61,43 +60,37 @@ public class Server {
6160
request = try self.decoder.decode(Request.self, from: json)
6261
}
6362
catch {
64-
let error = GraphQLWSError.noType()
65-
messenger.error(error.message, code: error.code)
63+
self.error(.noType())
6664
return
6765
}
6866

6967
switch request.type {
7068
case .GQL_CONNECTION_INIT:
7169
guard let connectionInitRequest = try? self.decoder.decode(ConnectionInitRequest.self, from: json) else {
72-
let error = GraphQLWSError.invalidRequestFormat(messageType: .GQL_CONNECTION_INIT)
73-
messenger.error(error.message, code: error.code)
70+
self.error(.invalidRequestFormat(messageType: .GQL_CONNECTION_INIT))
7471
return
7572
}
7673
self.onConnectionInit(connectionInitRequest, messenger)
7774
case .GQL_START:
7875
guard let startRequest = try? self.decoder.decode(StartRequest.self, from: json) else {
79-
let error = GraphQLWSError.invalidRequestFormat(messageType: .GQL_START)
80-
messenger.error(error.message, code: error.code)
76+
self.error(.invalidRequestFormat(messageType: .GQL_START))
8177
return
8278
}
8379
self.onStart(startRequest, messenger)
8480
case .GQL_STOP:
8581
guard let stopRequest = try? self.decoder.decode(StopRequest.self, from: json) else {
86-
let error = GraphQLWSError.invalidRequestFormat(messageType: .GQL_STOP)
87-
messenger.error(error.message, code: error.code)
82+
self.error(.invalidRequestFormat(messageType: .GQL_STOP))
8883
return
8984
}
9085
self.onStop(stopRequest, messenger)
9186
case .GQL_CONNECTION_TERMINATE:
9287
guard let connectionTerminateRequest = try? self.decoder.decode(ConnectionTerminateRequest.self, from: json) else {
93-
let error = GraphQLWSError.invalidRequestFormat(messageType: .GQL_CONNECTION_TERMINATE)
94-
messenger.error(error.message, code: error.code)
88+
self.error(.invalidRequestFormat(messageType: .GQL_CONNECTION_TERMINATE))
9589
return
9690
}
9791
self.onConnectionTerminate(connectionTerminateRequest, messenger)
9892
case .unknown:
99-
let error = GraphQLWSError.invalidType()
100-
messenger.error(error.message, code: error.code)
93+
self.error(.invalidType())
10194
}
10295
}
10396
}
@@ -123,17 +116,15 @@ public class Server {
123116

124117
private func onConnectionInit(_ connectionInitRequest: ConnectionInitRequest, _ messenger: Messenger) {
125118
guard !initialized else {
126-
let error = GraphQLWSError.tooManyInitializations()
127-
messenger.error(error.message, code: error.code)
119+
self.error(.tooManyInitializations())
128120
return
129121
}
130122

131123
do {
132124
try self.auth(connectionInitRequest)
133125
}
134126
catch {
135-
let error = GraphQLWSError.unauthorized()
136-
messenger.error(error.message, code: error.code)
127+
self.error(.unauthorized())
137128
return
138129
}
139130
initialized = true
@@ -143,8 +134,7 @@ public class Server {
143134

144135
private func onStart(_ startRequest: StartRequest, _ messenger: Messenger) {
145136
guard initialized else {
146-
let error = GraphQLWSError.notInitialized()
147-
messenger.error(error.message, code: error.code)
137+
self.error(.notInitialized())
148138
return
149139
}
150140

@@ -165,8 +155,7 @@ public class Server {
165155
subscribeFuture.whenSuccess { result in
166156
guard let streamOpt = result.stream else {
167157
// API issue - subscribe resolver isn't stream
168-
let error = GraphQLWSError.internalAPIStreamIssue()
169-
messenger.error(error.message, code: error.code)
158+
self.error(.internalAPIStreamIssue())
170159
return
171160
}
172161
let stream = streamOpt as! ObservableSubscriptionEventStream
@@ -193,8 +182,7 @@ public class Server {
193182
).disposed(by: self.disposeBag)
194183
}
195184
subscribeFuture.whenFailure { error in
196-
let error = GraphQLWSError.graphQLError(error)
197-
_ = messenger.error(error.message, code: error.code)
185+
self.error(.graphQLError(error))
198186
}
199187
}
200188
else {
@@ -214,8 +202,7 @@ public class Server {
214202

215203
private func onStop(_: StopRequest, _ messenger: Messenger) {
216204
guard initialized else {
217-
let error = GraphQLWSError.notInitialized()
218-
messenger.error(error.message, code: error.code)
205+
self.error(.notInitialized())
219206
return
220207
}
221208
onExit()
@@ -291,4 +278,10 @@ public class Server {
291278
private func sendError(_ errorMessage: String, id: String) {
292279
self.sendError(GraphQLError(message: errorMessage), id: id)
293280
}
281+
282+
/// Send an error through the messenger and close the connection
283+
private func error(_ error: GraphQLWSError) {
284+
guard let messenger = messenger else { return }
285+
messenger.error(error.message, code: error.code.rawValue)
286+
}
294287
}

Tests/GraphQLWSTests/GraphQLWSTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class GraphqlWsTests: XCTestCase {
6868
wait(for: [completeExpectation], timeout: 2)
6969
XCTAssertEqual(
7070
messages,
71-
["4407: Connection not initialized"]
71+
["\(ErrorCode.notInitialized): Connection not initialized"]
7272
)
7373
}
7474

@@ -96,7 +96,7 @@ class GraphqlWsTests: XCTestCase {
9696
wait(for: [completeExpectation], timeout: 2)
9797
XCTAssertEqual(
9898
messages,
99-
["4401: Unauthorized"]
99+
["\(ErrorCode.unauthorized): Unauthorized"]
100100
)
101101
}
102102

0 commit comments

Comments
 (0)