Skip to content

Commit 280fd4a

Browse files
[WIP] Implement room lifecycle spec
This is based on [1] at aa7455d. It’s generated some questions, which I’ve asked on that PR. I started implementing this as part of #19, before realising that implementing the spec is not the aim of that task. So, putting this work on hold until we pick it up again in #28. So far, only the ATTACH operation is implemented. [1] ably/specification#200 I have since updated with error names @ bcb7390 other stuff done since first version of this commit: - start implementing the low-hanging fruit of DETACH all the infrastructure in place for feature-specific errors used generic type for contributor so that i can access the mock-specific properties of the contributor's channel in the tests without having to create channels and then create contributors from those wip detachment errors further with detachment errors wip trying to see if there aren't 2 status updates Revert "wip trying to see if there aren't 2 status updates" This reverts commit 63dd9b9. Doesn’t work. implement CHA-RL2h2 wip channel detach retry a few updates to older bits implement more of RELEASE comment wip done RELEASE
1 parent 9014b0c commit 280fd4a

File tree

10 files changed

+1175
-4
lines changed

10 files changed

+1175
-4
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ To check formatting and code quality, run `swift run BuildTool lint`. Run with `
2828
- We should aim to make it easy for consumers of the SDK to be able to mock out the SDK in the tests for their own code. A couple of things that will aid with this:
2929
- Describe the SDK’s functionality via protocols (when doing so would still be sufficiently idiomatic to Swift).
3030
- When defining a `struct` that is emitted by the public API of the library, make sure to define a public memberwise initializer so that users can create one to be emitted by their mocks. (There is no way to make Swift’s autogenerated memberwise initializer public, so you will need to write one yourself. In Xcode, you can do this by clicking at the start of the type declaration and doing Editor → Refactor → Generate Memberwise Initializer.)
31+
- TODO something about adding spec points in code and tests
3132

3233
## Building for Swift 6
3334

Sources/AblyChat/Errors.swift

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,25 @@ public enum ErrorCode: Int {
1616
/// TODO this code is a guess, revisit in https://github.com/ably-labs/ably-chat-swift/issues/32
1717
case inconsistentRoomOptions = 1
1818

19+
// TODO: describe, and code is a guess
20+
case channelAttachResultedInSuspended = 2
21+
case channelAttachResultedInFailed = 3
22+
23+
case roomInFailedState = 102_101 // CHA-RL2d
24+
case roomIsReleasing = 102_102 // CHA-RL1b, CHA-RL2b
25+
case roomIsReleased = 102_103 // CHA-RL1c, CHA-RL2c
26+
27+
case messagesDetachmentFailed = 102_050
28+
case presenceDetachmentFailed = 102_051
29+
case reactionsDetachmentFailed = 102_052
30+
case occupancyDetachmentFailed = 102_053
31+
case typingDetachmentFailed = 102_054
32+
1933
/// The ``ARTErrorInfo.statusCode`` that should be returned for this error.
2034
internal var statusCode: Int {
2135
// TODO: These are currently a guess, revisit in https://github.com/ably-labs/ably-chat-swift/issues/32
2236
switch self {
23-
case .inconsistentRoomOptions:
37+
case .inconsistentRoomOptions, .channelAttachResultedInSuspended, .channelAttachResultedInFailed, .roomInFailedState, .roomIsReleasing, .roomIsReleased, .messagesDetachmentFailed, .presenceDetachmentFailed, .reactionsDetachmentFailed, .occupancyDetachmentFailed, .typingDetachmentFailed:
2438
400
2539
}
2640
}
@@ -29,16 +43,45 @@ public enum ErrorCode: Int {
2943
/**
3044
The errors thrown by the Chat SDK.
3145

32-
This type exists in addition to ``ErrorCode`` to allow us to attach metadata which can be incorporated into the error’s `localizedDescription`.
46+
This type exists in addition to ``ErrorCode`` to allow us to attach metadata which can be incorporated into the error’s `localizedDescription` and `cause`.
3347
*/
3448
internal enum ChatError {
3549
case inconsistentRoomOptions(requested: RoomOptions, existing: RoomOptions)
50+
case channelAttachResultedInSuspended(underlyingError: ARTErrorInfo)
51+
case channelAttachResultedInFailed(underlyingError: ARTErrorInfo)
52+
case roomInFailedState
53+
case roomIsReleasing
54+
case roomIsReleased
55+
case detachmentFailed(feature: RoomFeature, underlyingError: ARTErrorInfo)
3656

3757
/// The ``ARTErrorInfo.code`` that should be returned for this error.
3858
internal var code: ErrorCode {
3959
switch self {
4060
case .inconsistentRoomOptions:
4161
.inconsistentRoomOptions
62+
case .channelAttachResultedInSuspended:
63+
.channelAttachResultedInSuspended
64+
case .channelAttachResultedInFailed:
65+
.channelAttachResultedInFailed
66+
case .roomInFailedState:
67+
.roomInFailedState
68+
case .roomIsReleasing:
69+
.roomIsReleasing
70+
case .roomIsReleased:
71+
.roomIsReleased
72+
case let .detachmentFailed(feature, _):
73+
switch feature {
74+
case .messages:
75+
.messagesDetachmentFailed
76+
case .occupancy:
77+
.occupancyDetachmentFailed
78+
case .presence:
79+
.presenceDetachmentFailed
80+
case .reactions:
81+
.reactionsDetachmentFailed
82+
case .typing:
83+
.typingDetachmentFailed
84+
}
4285
}
4386
}
4487

@@ -47,6 +90,49 @@ internal enum ChatError {
4790
switch self {
4891
case let .inconsistentRoomOptions(requested, existing):
4992
"Rooms.get(roomID:options:) was called with a different set of room options than was used on a previous call. You must first release the existing room instance using Rooms.release(roomID:). Requested options: \(requested), existing options: \(existing)"
93+
case .channelAttachResultedInSuspended:
94+
"TODO"
95+
case .channelAttachResultedInFailed:
96+
"TODO"
97+
case .roomInFailedState:
98+
"Cannot perform operation because the room is in a failed state."
99+
case .roomIsReleasing:
100+
"Cannot perform operation because the room is in a releasing state."
101+
case .roomIsReleased:
102+
"Cannot perform operation because the room is in a released state."
103+
case let .detachmentFailed(feature, _):
104+
{
105+
let description = switch feature {
106+
case .messages:
107+
"messages"
108+
case .occupancy:
109+
"occupancy"
110+
case .presence:
111+
"presence"
112+
case .reactions:
113+
"reactions"
114+
case .typing:
115+
"typing"
116+
}
117+
return "The \(description) feature failed to detach."
118+
}()
119+
}
120+
}
121+
122+
/// The ``ARTErrorInfo.cause`` that should be returned for this error.
123+
internal var cause: ARTErrorInfo? {
124+
switch self {
125+
case let .channelAttachResultedInSuspended(underlyingError):
126+
underlyingError
127+
case let .channelAttachResultedInFailed(underlyingError):
128+
underlyingError
129+
case let .detachmentFailed(_, underlyingError):
130+
underlyingError
131+
case .inconsistentRoomOptions,
132+
.roomInFailedState,
133+
.roomIsReleasing,
134+
.roomIsReleased:
135+
nil
50136
}
51137
}
52138
}
@@ -58,6 +144,11 @@ internal extension ARTErrorInfo {
58144
userInfo["ARTErrorInfoStatusCode"] = chatError.code.statusCode
59145
userInfo[NSLocalizedDescriptionKey] = chatError.localizedDescription
60146

147+
// TODO: This is kind of an implementation detail (that NSUnderlyingErrorKey is what populates `cause`); consider documenting in ably-cocoa as part of https://github.com/ably-labs/ably-chat-swift/issues/32.
148+
if let cause = chatError.cause {
149+
userInfo[NSUnderlyingErrorKey] = cause
150+
}
151+
61152
self.init(
62153
domain: errorDomain,
63154
code: chatError.code.rawValue,

Sources/AblyChat/RoomFeature.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// The features offered by a chat room.
2+
internal enum RoomFeature {
3+
case messages
4+
case presence
5+
case reactions
6+
case occupancy
7+
case typing
8+
}

0 commit comments

Comments
 (0)