Skip to content

Commit

Permalink
Add unsupportedUserLocation case to GenerateContentError (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewheard authored Jan 26, 2024
1 parent db2da90 commit ce40a67
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Sources/GoogleAI/Errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ struct RPCError: Error {
func isInvalidAPIKeyError() -> Bool {
return errorInfo?.reason == "API_KEY_INVALID"
}

func isUnsupportedUserLocationError() -> Bool {
return message == RPCErrorMessage.unsupportedUserLocation.rawValue
}
}

extension RPCError: Decodable {
Expand Down Expand Up @@ -175,6 +179,10 @@ enum RPCStatus: String, Decodable {
case dataLoss = "DATA_LOSS"
}

enum RPCErrorMessage: String {
case unsupportedUserLocation = "User location is not supported for the API use."
}

enum InvalidCandidateError: Error {
case emptyContent(underlyingError: Error)
case malformedContent(underlyingError: Error)
Expand Down
10 changes: 10 additions & 0 deletions Sources/GoogleAI/GenerateContentError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,14 @@ public enum GenerateContentError: Error {

/// The provided API key is invalid.
case invalidAPIKey

/// The user's location (region) is not supported by the API.
///
/// See the Google documentation for a
/// [list of regions](https://ai.google.dev/available_regions#available_regions)
/// (countries and territories) where the API is available.
///
/// - Important: The API is only available in
/// [specific regions](https://ai.google.dev/available_regions#available_regions).
case unsupportedUserLocation
}
2 changes: 2 additions & 0 deletions Sources/GoogleAI/GenerativeModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ public final class GenerativeModel {
return error
} else if let error = error as? RPCError, error.isInvalidAPIKeyError() {
return GenerateContentError.invalidAPIKey
} else if let error = error as? RPCError, error.isUnsupportedUserLocationError() {
return GenerateContentError.unsupportedUserLocation
}
return GenerateContentError.internalError(underlying: error)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"error": {
"code": 400,
"message": "User location is not supported for the API use.",
"status": "FAILED_PRECONDITION",
"details": [
{
"@type": "type.googleapis.com/google.rpc.DebugInfo",
"detail": "[ORIGINAL ERROR] generic::failed_precondition: User location is not supported for the API use. [google.rpc.error_details_ext] { message: \"User location is not supported for the API use.\" }"
}
]
}
}
38 changes: 38 additions & 0 deletions Tests/GoogleAITests/GenerativeModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,24 @@ final class GenerativeModelTests: XCTestCase {
}
}

func testGenerateContent_failure_unsupportedUserLocation() async throws {
MockURLProtocol
.requestHandler = try httpRequestHandler(
forResource: "unary-failure-unsupported-user-location",
withExtension: "json",
statusCode: 400
)

do {
_ = try await model.generateContent(testPrompt)
XCTFail("Should throw GenerateContentError.unsupportedUserLocation; no error thrown.")
} catch GenerateContentError.unsupportedUserLocation {
return
}

XCTFail("Expected an unsupported user location error.")
}

func testGenerateContent_failure_nonHTTPResponse() async throws {
MockURLProtocol.requestHandler = try nonHTTPRequestHandler()

Expand Down Expand Up @@ -708,6 +726,26 @@ final class GenerativeModelTests: XCTestCase {
XCTFail("Expected an internal decoding error.")
}

func testGenerateContentStream_failure_unsupportedUserLocation() async throws {
MockURLProtocol
.requestHandler = try httpRequestHandler(
forResource: "unary-failure-unsupported-user-location",
withExtension: "json",
statusCode: 400
)

let stream = model.generateContentStream(testPrompt)
do {
for try await content in stream {
XCTFail("Unexpected content in stream: \(content)")
}
} catch GenerateContentError.unsupportedUserLocation {
return
}

XCTFail("Expected an unsupported user location error.")
}

// MARK: - Count Tokens

func testCountTokens_succeeds() async throws {
Expand Down

0 comments on commit ce40a67

Please sign in to comment.