-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ECO-5144] Implement CHA-PR3h etc #163
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThe pull request introduces significant changes to the error handling mechanisms within the Ably Chat SDK. Key modifications include updates to the Changes
Assessment against linked issues
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (6)
Sources/AblyChat/DefaultMessages.swift (1)
237-244
: Consider adding error code documentationThe error message "Channel failed to attach" could be more descriptive about the reason for failure and potential remediation steps.
Consider enhancing the error message:
- message: "Channel failed to attach" + message: "Channel failed to attach. This may occur due to network issues or invalid channel state. Please check network connectivity and retry."Sources/AblyChat/RoomLifecycleManager.swift (1)
1234-1235
: LGTM: Error handling matches specificationsThe error handling correctly implements the referenced specifications (CHA-PR3h, CHA-PR10h, CHA-PR6h, CHA-T2g) by throwing
.presenceOperationRequiresRoomAttach
with the requesting feature.Consider grouping the specification references in the comment for better readability:
- // CHA-PR3h, CHA-PR10h, CHA-PR6h, CHA-T2g + // Presence operation requirements: + // - CHA-PR3h: Enter + // - CHA-PR10h: Update + // - CHA-PR6h: Leave + // - CHA-T2g: GetSources/AblyChat/Errors.swift (4)
113-123
: UnifyCaseThatImpliesVariableStatusCode
withErrorCode
The
CaseThatImpliesVariableStatusCode
enum contains a single case that mirrors theErrorCode
enum. To simplify the code structure, consider integrating variable status codes directly into theErrorCode
enum using associated values or a mapping mechanism.For example:
public enum ErrorCode: Int { // Existing cases... case roomInInvalidState = 102_107 // ... /// Function to get the status code for variable status code errors. func statusCode(forError error: ChatError) -> Int { switch error { case .roomTransitionedToInvalidStateForPresenceOperation: return 500 case .presenceOperationRequiresRoomAttach: return 400 default: return self.fixedStatusCode ?? 0 // Use the fixed status code if available } } }This approach centralizes the error code and status code handling within the
ErrorCode
enum.
128-148
: SimplifyErrorCodeAndStatusCode
by leveraging associated valuesThe
ErrorCodeAndStatusCode
enum adds complexity by wrapping error codes with status codes. To streamline error handling, consider using associated values within theErrorCode
enum to represent variable status codes, which can simplify the codebase and make error management more intuitive.Example modification:
public enum ErrorCode: Int { // Existing cases... case roomInInvalidState(statusCode: Int) // ... /// Function to get the status code. var statusCode: Int { switch self { case .roomInInvalidState(let statusCode): return statusCode default: return self.fixedStatusCode ?? 0 } } }This change allows you to store the status code directly with the error code, eliminating the need for the separate
ErrorCodeAndStatusCode
enum.
265-265
: Enhance error message forroomTransitionedToInvalidStateForPresenceOperation
The current error message is generic and may not provide sufficient context to the developer or user. Consider including specific details about the invalid state or providing guidance on how to rectify the issue.
For example:
case .roomTransitionedToInvalidStateForPresenceOperation: "The room operation failed because the room has transitioned to a state that does not allow presence operations. Please ensure the room is in a valid state before retrying."
Line range hint
293-303
: Avoid reliance on privateARTErrorInfo
implementation detailsThe code uses hardcoded keys like
"ARTErrorInfoStatusCode"
and comments indicate copying from private implementations inably-cocoa
. This approach can lead to fragile code if the underlying library changes. It's recommended to:
- Request public APIs: Reach out to the
ably-cocoa
maintainers to expose necessary properties or methods needed for proper error handling.- Encapsulate error construction: Create a wrapper or utility that safely constructs
ARTErrorInfo
without depending on internal implementations.By reducing dependency on private APIs, you ensure long-term stability and compatibility of your SDK.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
Sources/AblyChat/DefaultMessages.swift
(1 hunks)Sources/AblyChat/Errors.swift
(6 hunks)Sources/AblyChat/RoomFeature.swift
(1 hunks)Sources/AblyChat/RoomLifecycleManager.swift
(1 hunks)Tests/AblyChatTests/DefaultRoomLifecycleManagerTests.swift
(13 hunks)Tests/AblyChatTests/DefaultRoomsTests.swift
(1 hunks)Tests/AblyChatTests/Helpers/Helpers.swift
(1 hunks)
🔇 Additional comments (13)
Tests/AblyChatTests/Helpers/Helpers.swift (2)
7-7
: LGTM! Improved error handling structure
The function signature change from withCode
to withCodeAndStatusCode
better reflects the structured approach to error handling, aligning with the PR's objective to improve error state management.
13-14
: LGTM! Verify test coverage for the new error validation
The error validation logic has been properly updated to handle both error codes and status codes separately through the new ErrorCodeAndStatusCode
type.
Let's verify the test coverage for this new error validation structure:
✅ Verification successful
Based on the search results, I can generate the final response as we have sufficient information about the test coverage of the new error validation structure.
Test coverage for the new error validation is comprehensive and well-structured
The codebase shows thorough test coverage for the new error validation structure with ErrorCodeAndStatusCode
:
- Multiple test cases in
DefaultRoomsTests.swift
andDefaultRoomLifecycleManagerTests.swift
validate various error scenarios - Tests cover both fixed status codes (e.g.,
.roomIsReleasing
,.roomIsReleased
,.roomInFailedState
) and variable status codes - Error validation includes checking for specific error causes and custom messages
- Test helper
isChatError
properly validates both the error code and status code components
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for test cases using the new error validation structure
# Search for test cases using isChatError with the new parameter structure
rg -A 5 "isChatError.*withCodeAndStatusCode" "Tests/"
# Search for the definition and usage of ErrorCodeAndStatusCode to ensure proper test coverage
ast-grep --pattern 'enum ErrorCodeAndStatusCode {
$$$
}'
Length of output: 8176
Sources/AblyChat/RoomFeature.swift (2)
44-48
: Documentation updates look good, verifying implementation alignment.
The documentation changes clearly describe the error handling scenarios and align well with the PR objectives. The updates properly reflect the transition from error code 40000 to specific error types.
Let's verify that the implementation matches the documented behavior:
✅ Verification successful
Let me gather more information about the implementation of waitToBeAbleToPerformPresenceOperations
to verify it fully matches the documented behavior.
Implementation correctly matches documented behavior
The implementation in RoomLifecycleManager.swift
fully aligns with the documented error handling scenarios:
- For ATTACHING status (CHA-RL9): The code waits for the next room status change and throws
roomTransitionedToInvalidStateForPresenceOperation
if the new status is not ATTACHED. - For ATTACHED status (CHA-PR3e): The code returns immediately as documented.
- For other statuses (CHA-PR3h): The code throws
presenceOperationRequiresRoomAttach
with status code 400.
The error types are properly defined in Errors.swift
with the correct status codes and messages.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify error handling implementation matches documentation
# Search for the error handling implementation in the codebase
# Check for roomTransitionedToInvalidStateForPresenceOperation implementation
rg -t swift "roomTransitionedToInvalidStateForPresenceOperation" -A 5
# Check for presenceOperationRequiresRoomAttach implementation
rg -t swift "presenceOperationRequiresRoomAttach" -A 5
# Check for waitToBeAbleToPerformPresenceOperations implementation
ast-grep --pattern 'func waitToBeAbleToPerformPresenceOperations'
Length of output: 6535
Script:
#!/bin/bash
# Search for the implementation of waitToBeAbleToPerformPresenceOperations
rg -t swift "func waitToBeAbleToPerformPresenceOperations.*\{" -A 20
# Also check for any switch statements handling room states
rg -t swift "switch.*status.*\{" -A 15 Sources/AblyChat/RoomLifecycleManager.swift
Length of output: 16350
Line range hint 63-65
: Verify error propagation in DefaultFeatureChannel.
The implementation correctly delegates to roomLifecycleManager, maintaining good separation of concerns. However, we should verify that errors are properly propagated through the chain.
Let's verify the error propagation chain:
✅ Verification successful
Let me gather more information about the error handling implementation.
Based on the comprehensive analysis of the error handling implementation, I can now provide the final response:
Error propagation is properly implemented in the waitToBeAbleToPerformPresenceOperations chain
The implementation correctly propagates errors through the following chain:
DefaultFeatureChannel
delegates toRoomLifecycleManager
RoomLifecycleManager
implements proper error handling for different states:- Throws
ARTErrorInfo
withChatError.presenceOperationRequiresRoomAttach
when not in correct state - Propagates errors during state transitions with proper error context
- Handles attachment failures with appropriate error wrapping
- Throws
The error handling follows the documented behavior in the function comments and is well-tested as evidenced by the comprehensive test suite in DefaultRoomLifecycleManagerTests
.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify error propagation through the call chain
# Check RoomLifecycleManager implementation
ast-grep --pattern 'func waitToBeAbleToPerformPresenceOperations(requestedByFeature $$$) {
$$$
}'
# Check for error handling tests
rg -t swift "waitToBeAbleToPerformPresenceOperations.*throws" -A 5 --glob "*Tests.swift"
Length of output: 3015
Script:
#!/bin/bash
# Check the implementation of waitToBeAbleToPerformPresenceOperations in RoomLifecycleManager
rg -t swift "waitToBeAbleToPerformPresenceOperations.*throws" -B 5 -A 15
# Check for error types and handling
rg -t swift "ARTErrorInfo" -A 3
Length of output: 82093
Tests/AblyChatTests/DefaultRoomsTests.swift (1)
81-81
: LGTM! Error assertion update aligns with new error handling structure.
The change from withCode
to withCodeAndStatusCode
properly validates both the error code and status code, providing more comprehensive error checking. This aligns with the PR's objective of improving error handling mechanisms.
Let's verify the consistency of error handling across the test suite:
✅ Verification successful
Consider updating remaining withCode
assertions to use withCodeAndStatusCode
for consistency
The verification reveals inconsistent error assertion patterns across test files:
DefaultRoomLifecycleManagerTests.swift
uses both old.create(withCode:)
and newwithCodeAndStatusCode
patternsDefaultMessagesTests.swift
andChatAPITests.swift
still use the old.create(withCode:)
pattern
Let's verify if these are intentionally different or need updating:
The old-style error assertions are used correctly and don't require updates
After analyzing the context:
- In
DefaultMessagesTests.swift
, the old-style assertion is used to test a specific Ably Realtime error (ARTErrorInfo) with status code, which is correct. - In
ChatAPITests.swift
, it's used to mock an internal server error from Ably's SDK. - In
DefaultRoomLifecycleManagerTests.swift
, it's used for creating mock errors in test setup, not for asserting Chat SDK-specific errors.
The new withCodeAndStatusCode
pattern is correctly used for Chat SDK-specific error assertions, while the old withCode
pattern is appropriately used for Ably Realtime SDK errors and mocks. This separation is intentional and correct.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining old-style error assertions that might need updating
# Search for old-style error assertions
rg "withCode:" "Tests/"
# Search for new-style error assertions for comparison
rg "withCodeAndStatusCode:" "Tests/"
Length of output: 3193
Script:
#!/bin/bash
# Check the context of old-style assertions to understand their usage
rg -B 2 -A 2 "withCode:" Tests/AblyChatTests/DefaultMessagesTests.swift Tests/AblyChatTests/ChatAPITests.swift Tests/AblyChatTests/DefaultRoomLifecycleManagerTests.swift
Length of output: 3179
Sources/AblyChat/DefaultMessages.swift (2)
237-241
: Verify error code mapping
The change introduces a new error code case messagesAttachmentFailed
. We should verify that this maps to the correct error code and status code as per the API specifications.
✅ Verification successful
Error code mapping is correctly implemented
The verification confirms that:
messagesAttachmentFailed
is defined with error code 102001 in theErrorCode
enum- It's properly mapped as a fixed status code case
- The error code and status code are correctly propagated through the error handling system
- The implementation is consistent with test cases that verify this behavior
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for the error code definition and its usage
ast-grep --pattern 'enum ErrorCode {
$$$
case messagesAttachmentFailed
$$$
}'
Length of output: 85
Script:
#!/bin/bash
# Search for the error code definition and its usage with a broader pattern
rg -A 10 "enum ErrorCode" --type swift
Length of output: 1792
Script:
#!/bin/bash
# Search for messagesAttachmentFailed usage
rg "messagesAttachmentFailed" --type swift
Length of output: 1034
Script:
#!/bin/bash
# Search for CaseThatImpliesFixedStatusCode
rg "CaseThatImpliesFixedStatusCode" --type swift -A 5
Length of output: 1602
236-236
: Consider addressing error handling TODO
There's a TODO comment about revisiting error handling (issue #32). Given that this PR implements significant error handling changes, it might be worth addressing this TODO now to ensure consistency.
Let's check the referenced issue:
Sources/AblyChat/RoomLifecycleManager.swift (1)
1228-1228
: LGTM: Improved error handling clarity
The change from error code 40000 to .roomTransitionedToInvalidStateForPresenceOperation
provides better error context by including the cause from the room status change.
Tests/AblyChatTests/DefaultRoomLifecycleManagerTests.swift (3)
148-148
: LGTM: Consistent error code verification for room state errors
The changes correctly implement the standardized error verification using fixedStatusCode
for room state errors (roomIsReleasing
and roomIsReleased
). This aligns with the PR objective to improve error handling.
Also applies to: 163-163
376-376
: LGTM: Comprehensive error code verification updates
The changes systematically update error verification across multiple test cases to use fixedStatusCode
for:
- Message attachment failures
- Room state errors (releasing, released, failed)
- Presence detachment failures
This provides consistent error handling verification throughout the test suite.
Also applies to: 457-457, 564-564, 579-579, 598-598, 697-697, 1098-1098
Line range hint 2090-2099
: LGTM: Proper implementation of RoomInInvalidState error handling
The changes correctly implement the new RoomInInvalidState
error handling with:
- Proper error cause propagation
- Appropriate status codes (500 for transitions, 400 for initial state)
- Clear error messages
- Comprehensive spec documentation
This fulfills the PR objective to replace error code 40000 with RoomInInvalidState
.
Also applies to: 2118-2121, 2124-2126, 2139-2140
Sources/AblyChat/Errors.swift (2)
205-209
: Ensure consistent handling of variable status codes
The status codes assigned to .roomTransitionedToInvalidStateForPresenceOperation
(500) and .presenceOperationRequiresRoomAttach
(400) are hardcoded but categorized under variableStatusCode
. Verify whether these status codes are indeed variable or should be fixed. If they are fixed, consider moving them to the fixed status code category for clarity and consistency.
If the status codes are expected to vary based on context, ensure that the mechanisms to assign dynamic status codes are correctly implemented.
277-277
: Confirm proper propagation of underlying error causes
When handling .roomTransitionedToInvalidStateForPresenceOperation
, ensure that the optional cause
is being correctly propagated and logged. This will aid in debugging by providing the root cause of the error when available.
Double-check that any wrapped ARTErrorInfo
instances are included in the error reporting mechanisms and are accessible to the developers.
CI isn't running because Actions have become disabled after we migrated this repo out of ably-labs. But will put into review anyway. |
7a0952e
to
951e66b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
Sources/AblyChat/Errors.swift (1)
112-122
: Add documentation explaining variable status codesConsider adding documentation to explain when and why certain error codes have variable status codes versus fixed ones. This would help maintainers understand when to use each type.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (4)
Sources/AblyChat/Errors.swift
(6 hunks)Sources/AblyChat/RoomFeature.swift
(1 hunks)Sources/AblyChat/RoomLifecycleManager.swift
(1 hunks)Tests/AblyChatTests/DefaultRoomLifecycleManagerTests.swift
(13 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- Sources/AblyChat/RoomFeature.swift
- Sources/AblyChat/RoomLifecycleManager.swift
🔇 Additional comments (15)
Sources/AblyChat/Errors.swift (4)
125-150
: LGTM! Well-structured error code and status code handling
The implementation provides a clean separation between fixed and variable status codes while maintaining type safety.
166-209
: LGTM! Successfully implements CHA-PR3h requirements
The changes correctly implement the requirement to throw RoomInInvalidState
with appropriate status codes (400 for presence operation requiring room attach, 500 for room transition to invalid state). The spec references in comments provide good traceability.
37-110
: 🛠️ Refactor suggestion
Consider refactoring to reduce code duplication
The CaseThatImpliesFixedStatusCode
enum duplicates cases from ErrorCode
, which could lead to maintenance challenges.
The previous review comment suggesting refactoring to eliminate redundancy using a computed property in ErrorCode
is still applicable.
Line range hint 293-303
: Consider addressing TODOs in a follow-up PR
The TODOs reference implementation details that should be revisited in issue #32, particularly around:
- The copying of ARTErrorInfo creation logic
- Documentation of NSUnderlyingErrorKey usage in ably-cocoa
Tests/AblyChatTests/DefaultRoomLifecycleManagerTests.swift (11)
148-148
: LGTM! Error assertion updated for room releasing state.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
163-163
: LGTM! Error assertion updated for room released state.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
376-376
: LGTM! Error assertion updated for messages attachment failure.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
457-457
: LGTM! Error assertion updated for messages attachment failure.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
564-564
: LGTM! Error assertion updated for room releasing state.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
579-579
: LGTM! Error assertion updated for room released state.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
598-598
: LGTM! Error assertion updated for room in failed state.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
697-697
: LGTM! Error assertion updated for presence detachment failure.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
1098-1098
: LGTM! Error assertion updated for presence detachment failure.
The change from withCode
to withCodeAndStatusCode
aligns with the PR objective of improving error handling.
Line range hint 2090-2099
: LGTM! Error assertion updated with specific status code for room in invalid state.
The change implements the new error handling with status code 500 for invalid room state during presence operations, aligning with the PR objective.
Line range hint 2118-2140
: LGTM! Error assertion updated with specific status code and message for room in invalid state.
The change implements the new error handling with:
- Status code 400 for invalid room state
- Clear error message explaining that the room must be attached first
- Proper test coverage for the error scenario
This aligns perfectly with the PR objective of improving error handling clarity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm
Mistake in 9c97883.
This is in preparation for implementing CHA-PR3h, in which a given numerical error code no longer necessarily implies a specific status code (specifically, RoomInInvalidState may now have a 400 or 500 status code depending on the context in which it is thrown). The internal API introduced here is a bit convoluted and verbose, but I’ve done it this way for two reasons: 1. It reflects the way the spec is written; most of the time a numeric code has a status code written alongside it 2. For the numerical error codes that _do_ always imply a certain status code, I want to be able to get that status code still, so that the existing Messages code that throws an error with the messagesAttachmentFailed code, as well as the isChatError(…) test helper, continue to work as they currently do.
Resolves #151.
951e66b
to
cf769a1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
Sources/AblyChat/Errors.swift (1)
Line range hint
293-303
: Consider improving documentation for ARTErrorInfo initialization.While the implementation is correct, the TODO comments suggest documentation improvements needed in ably-cocoa. Consider:
- Documenting the NSUnderlyingErrorKey usage
- Clarifying the ARTErrorInfoStatusCode implementation details
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
Sources/AblyChat/DefaultMessages.swift
(1 hunks)Sources/AblyChat/Errors.swift
(6 hunks)Sources/AblyChat/RoomFeature.swift
(1 hunks)Sources/AblyChat/RoomLifecycleManager.swift
(1 hunks)Tests/AblyChatTests/DefaultRoomLifecycleManagerTests.swift
(13 hunks)Tests/AblyChatTests/DefaultRoomsTests.swift
(1 hunks)Tests/AblyChatTests/Helpers/Helpers.swift
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- Tests/AblyChatTests/DefaultRoomsTests.swift
- Sources/AblyChat/DefaultMessages.swift
- Sources/AblyChat/RoomLifecycleManager.swift
- Tests/AblyChatTests/Helpers/Helpers.swift
- Sources/AblyChat/RoomFeature.swift
🔇 Additional comments (6)
Sources/AblyChat/Errors.swift (3)
37-122
: Well-structured error code classification!
The separation of error codes into fixed and variable status codes improves error handling clarity and maintainability. The implementation is thorough with:
- Clear documentation of each enum's purpose
- Exhaustive case handling
- Type-safe conversion to numeric error codes
125-150
: Well-designed error code and status code pairing!
The ErrorCodeAndStatusCode
enum provides a type-safe way to handle error codes with their corresponding status codes. The implementation:
- Clearly separates fixed and variable status code cases
- Provides convenient access to both code and status code
- Maintains type safety throughout
204-209
: Successfully implemented CHA-PR3h requirements!
The changes correctly implement the new error handling requirements by:
- Adding proper status code handling for invalid room states (500 for transitions, 400 for presence operations)
- Including clear spec references in comments (CHA-RL9c, CHA-PR3h, etc.)
Tests/AblyChatTests/DefaultRoomLifecycleManagerTests.swift (3)
Line range hint 148-163
: Comprehensive error assertion updates!
The test assertions have been properly updated to verify both error codes and status codes using the new withCodeAndStatusCode
method. This ensures proper validation of the new error handling structure.
Line range hint 2090-2099
: Thorough testing of presence operation error handling!
The test properly verifies the new error handling requirements:
- Checks for RoomInInvalidState error with status code 500
- Verifies the error cause matches the room status change
- Validates the complete error chain
Line range hint 2118-2140
: Well-documented and implemented presence operation tests!
The test implementation:
- Properly references relevant specs (CHA-PR3h, CHA-PR10h, etc.)
- Verifies correct error message for room attachment requirement
- Validates the expected status code 400 for invalid states
Resolves #151. See commit messages for more details.
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Documentation
Tests