Add AI request error states
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import Foundation
|
||||
|
||||
public enum AIRequestState: Equatable, Sendable {
|
||||
case idle
|
||||
case loading
|
||||
case failed(AIProviderErrorState)
|
||||
}
|
||||
|
||||
public enum AIProviderErrorState: Equatable, Sendable {
|
||||
case offline
|
||||
case missingConfiguration
|
||||
case rateLimited(retryAfter: TimeInterval?)
|
||||
case unavailable
|
||||
case invalidResponse
|
||||
case unsupportedCapability
|
||||
}
|
||||
|
||||
public struct AIProviderErrorPresenter: Sendable {
|
||||
public init() {}
|
||||
|
||||
public func state(for error: Error) -> AIProviderErrorState {
|
||||
if let urlError = error as? URLError,
|
||||
urlError.code == .notConnectedToInternet || urlError.code == .networkConnectionLost {
|
||||
return .offline
|
||||
}
|
||||
|
||||
if let clientError = error as? OpenAIClientError {
|
||||
switch clientError {
|
||||
case .missingAPIKey:
|
||||
return .missingConfiguration
|
||||
case let .rateLimited(retryAfter):
|
||||
return .rateLimited(retryAfter: retryAfter)
|
||||
case .serverError, .unacceptableStatusCode:
|
||||
return .unavailable
|
||||
case .invalidResponse:
|
||||
return .invalidResponse
|
||||
}
|
||||
}
|
||||
|
||||
if error as? AIServiceCapabilityError != nil {
|
||||
return .unsupportedCapability
|
||||
}
|
||||
|
||||
return .unavailable
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import MusicAssistantCore
|
||||
import XCTest
|
||||
|
||||
final class AIRequestStateTests: XCTestCase {
|
||||
func testPresenterMapsOfflineAndProviderFailures() {
|
||||
let presenter = AIProviderErrorPresenter()
|
||||
|
||||
XCTAssertEqual(presenter.state(for: URLError(.notConnectedToInternet)), .offline)
|
||||
XCTAssertEqual(presenter.state(for: OpenAIClientError.missingAPIKey), .missingConfiguration)
|
||||
XCTAssertEqual(presenter.state(for: OpenAIClientError.rateLimited(retryAfter: 30)), .rateLimited(retryAfter: 30))
|
||||
XCTAssertEqual(presenter.state(for: OpenAIClientError.serverError(503)), .unavailable)
|
||||
XCTAssertEqual(presenter.state(for: OpenAIClientError.invalidResponse), .invalidResponse)
|
||||
XCTAssertEqual(presenter.state(for: AIServiceCapabilityError.discussionNotSupported), .unsupportedCapability)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -113,7 +113,7 @@ requirement is missing and blocks implementation, record it in
|
||||
## Phase 9 --- Quality
|
||||
|
||||
- [x] Add validation for contradictory/invalid project settings.
|
||||
- [ ] Add loading, offline and provider-error states.
|
||||
- [x] Add loading, offline and provider-error states.
|
||||
- [ ] Add accessibility labels and keyboard navigation.
|
||||
- [ ] Test project/version recovery.
|
||||
- [ ] Test AI output against locked user choices.
|
||||
|
||||
Reference in New Issue
Block a user