Skip to content

Commit

Permalink
Make status code available in APIError (#50)
Browse files Browse the repository at this point in the history
* Make status code available in APIError

* Spacing in readme example

* Deindent to match James's style
  • Loading branch information
lzell committed Jun 24, 2024
1 parent 60ec637 commit 2092e73
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ import SwiftOpenAI
let logprobs = choices.compactMap(\.logprobs)
dump(logprobs)
self.messages = choices.compactMap(\.message.content)
} catch APIError.responseUnsuccessful(let description, let statusCode) {
self.errorMessage = "Network error with status code: \(statusCode) and description: \(description)"
} catch {
self.errorMessage = "\(error)"
self.errorMessage = error.localizedDescription
}
}

Expand All @@ -44,8 +46,10 @@ import SwiftOpenAI
let content = result.choices.first?.delta.content ?? ""
self.message += content
}
} catch APIError.responseUnsuccessful(let description, let statusCode) {
self.errorMessage = "Network error with status code: \(statusCode) and description: \(description)"
} catch {
self.errorMessage = "\(error)"
self.errorMessage = error.localizedDescription
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,29 @@ let service = OpenAIServiceFactory.service(apiKey: apiKey, organizationID: ogani

That's all you need to begin accessing the full range of OpenAI endpoints.


### How to get the status code of network errors

You may want to build UI around the type of error that the API returns.
For example, a `429` means that your requests are being rate limited.
The `APIError` type has a case `responseUnsuccessful` with two associated values: a `description` and `statusCode`.
Here is a usage example using the chat completion API:

```
let service = OpenAIServiceFactory.service(apiKey: apiKey)
let parameters = ChatCompletionParameters(messages: [.init(role: .user, content: .text("hello world"))],
model: .gpt4o)
do {
let choices = try await service.startChat(parameters: parameters).choices
// Work with choices
} catch APIError.responseUnsuccessful(let description, let statusCode) {
print("Network error with status code: \(statusCode) and description: \(description)")
} catch {
print(error.localizedDescription)
}
```


### Audio

### Audio Transcriptions
Expand Down
19 changes: 12 additions & 7 deletions Sources/OpenAI/Public/Service/OpenAIService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Foundation
public enum APIError: Error {

case requestFailed(description: String)
case responseUnsuccessful(description: String)
case responseUnsuccessful(description: String, statusCode: Int)
case invalidData
case jsonDecodingFailure(description: String)
case dataCouldNotBeReadMissingData(description: String)
Expand All @@ -22,7 +22,7 @@ public enum APIError: Error {
public var displayDescription: String {
switch self {
case .requestFailed(let description): return description
case .responseUnsuccessful(let description): return description
case .responseUnsuccessful(let description, _): return description
case .invalidData: return "Invalid data"
case .jsonDecodingFailure(let description): return description
case .dataCouldNotBeReadMissingData(let description): return description
Expand Down Expand Up @@ -948,7 +948,8 @@ extension OpenAIService {
// If decoding fails, proceed with a general error message
errorMessage = "status code \(httpResponse.statusCode)"
}
throw APIError.responseUnsuccessful(description: errorMessage)
throw APIError.responseUnsuccessful(description: errorMessage,
statusCode: httpResponse.statusCode)
}
var content: [[String: Any]] = []
if let jsonString = String(data: data, encoding: .utf8) {
Expand Down Expand Up @@ -996,7 +997,8 @@ extension OpenAIService {
errorMessage += " - No error message provided"
}
}
throw APIError.responseUnsuccessful(description: errorMessage)
throw APIError.responseUnsuccessful(description: errorMessage,
statusCode: httpResponse.statusCode)
}
return data
}
Expand Down Expand Up @@ -1028,7 +1030,8 @@ extension OpenAIService {
// If decoding fails, proceed with a general error message
errorMessage = "status code \(httpResponse.statusCode)"
}
throw APIError.responseUnsuccessful(description: errorMessage)
throw APIError.responseUnsuccessful(description: errorMessage,
statusCode: httpResponse.statusCode)
}
#if DEBUG
print("DEBUG JSON FETCH API = \(try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any])")
Expand Down Expand Up @@ -1084,7 +1087,8 @@ extension OpenAIService {
// If decoding fails, proceed with a general error message
errorMessage = "status code \(httpResponse.statusCode)"
}
throw APIError.responseUnsuccessful(description: errorMessage)
throw APIError.responseUnsuccessful(description: errorMessage,
statusCode: httpResponse.statusCode)
}
return AsyncThrowingStream { continuation in
let task = Task {
Expand Down Expand Up @@ -1159,7 +1163,8 @@ extension OpenAIService {
// If decoding fails, proceed with a general error message
errorMessage = "status code \(httpResponse.statusCode)"
}
throw APIError.responseUnsuccessful(description: errorMessage)
throw APIError.responseUnsuccessful(description: errorMessage,
statusCode: httpResponse.statusCode)
}
return AsyncThrowingStream { continuation in
let task = Task {
Expand Down

0 comments on commit 2092e73

Please sign in to comment.