Skip to content

Commit fb856dc

Browse files
authored
[Vertex AI] Renamed RPCError to BackendError (#14027)
1 parent 0a49232 commit fb856dc

File tree

4 files changed

+78
-63
lines changed

4 files changed

+78
-63
lines changed

FirebaseVertexAI/Sources/Errors.swift

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -14,59 +14,6 @@
1414

1515
import Foundation
1616

17-
struct RPCError: Error {
18-
let httpResponseCode: Int
19-
let message: String
20-
let status: RPCStatus
21-
let details: [ErrorDetails]
22-
23-
private var errorInfo: ErrorDetails? {
24-
return details.first { $0.isErrorInfo() }
25-
}
26-
27-
init(httpResponseCode: Int, message: String, status: RPCStatus, details: [ErrorDetails]) {
28-
self.httpResponseCode = httpResponseCode
29-
self.message = message
30-
self.status = status
31-
self.details = details
32-
}
33-
34-
func isVertexAIInFirebaseServiceDisabledError() -> Bool {
35-
return details.contains { $0.isVertexAIInFirebaseServiceDisabledErrorDetails() }
36-
}
37-
}
38-
39-
extension RPCError: Decodable {
40-
enum CodingKeys: CodingKey {
41-
case error
42-
}
43-
44-
init(from decoder: Decoder) throws {
45-
let container = try decoder.container(keyedBy: CodingKeys.self)
46-
let status = try container.decode(ErrorStatus.self, forKey: .error)
47-
48-
if let code = status.code {
49-
httpResponseCode = code
50-
} else {
51-
httpResponseCode = -1
52-
}
53-
54-
if let message = status.message {
55-
self.message = message
56-
} else {
57-
message = "Unknown error."
58-
}
59-
60-
if let rpcStatus = status.status {
61-
self.status = rpcStatus
62-
} else {
63-
self.status = .unknown
64-
}
65-
66-
details = status.details
67-
}
68-
}
69-
7017
struct ErrorStatus {
7118
let code: Int?
7219
let message: String?

FirebaseVertexAI/Sources/GenerativeAIService.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ struct GenerativeAIService {
251251

252252
private func parseError(responseData: Data) -> Error {
253253
do {
254-
let rpcError = try JSONDecoder().decode(RPCError.self, from: responseData)
254+
let rpcError = try JSONDecoder().decode(BackendError.self, from: responseData)
255255
logRPCError(rpcError)
256256
return rpcError
257257
} catch {
@@ -262,7 +262,7 @@ struct GenerativeAIService {
262262

263263
// Log specific RPC errors that cannot be mitigated or handled by user code.
264264
// These errors do not produce specific GenerateContentError or CountTokensError cases.
265-
private func logRPCError(_ error: RPCError) {
265+
private func logRPCError(_ error: BackendError) {
266266
if error.isVertexAIInFirebaseServiceDisabledError() {
267267
VertexLog.error(code: .vertexAIInFirebaseAPIDisabled, """
268268
The Vertex AI in Firebase SDK requires the Vertex AI in Firebase API \
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import Foundation
16+
17+
struct BackendError: Error {
18+
let httpResponseCode: Int
19+
let message: String
20+
let status: RPCStatus
21+
let details: [ErrorDetails]
22+
23+
private var errorInfo: ErrorDetails? {
24+
return details.first { $0.isErrorInfo() }
25+
}
26+
27+
init(httpResponseCode: Int, message: String, status: RPCStatus, details: [ErrorDetails]) {
28+
self.httpResponseCode = httpResponseCode
29+
self.message = message
30+
self.status = status
31+
self.details = details
32+
}
33+
34+
func isVertexAIInFirebaseServiceDisabledError() -> Bool {
35+
return details.contains { $0.isVertexAIInFirebaseServiceDisabledErrorDetails() }
36+
}
37+
}
38+
39+
extension BackendError: Decodable {
40+
enum CodingKeys: CodingKey {
41+
case error
42+
}
43+
44+
init(from decoder: Decoder) throws {
45+
let container = try decoder.container(keyedBy: CodingKeys.self)
46+
let status = try container.decode(ErrorStatus.self, forKey: .error)
47+
48+
if let code = status.code {
49+
httpResponseCode = code
50+
} else {
51+
httpResponseCode = -1
52+
}
53+
54+
if let message = status.message {
55+
self.message = message
56+
} else {
57+
message = "Unknown error."
58+
}
59+
60+
if let rpcStatus = status.status {
61+
self.status = rpcStatus
62+
} else {
63+
self.status = .unknown
64+
}
65+
66+
details = status.details
67+
}
68+
}

FirebaseVertexAI/Tests/Unit/GenerativeModelTests.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ final class GenerativeModelTests: XCTestCase {
502502
do {
503503
_ = try await model.generateContent(testPrompt)
504504
XCTFail("Should throw GenerateContentError.internalError; no error thrown.")
505-
} catch let GenerateContentError.internalError(error as RPCError) {
505+
} catch let GenerateContentError.internalError(error as BackendError) {
506506
XCTAssertEqual(error.httpResponseCode, 400)
507507
XCTAssertEqual(error.status, .invalidArgument)
508508
XCTAssertEqual(error.message, "API key not valid. Please pass a valid API key.")
@@ -524,7 +524,7 @@ final class GenerativeModelTests: XCTestCase {
524524
do {
525525
_ = try await model.generateContent(testPrompt)
526526
XCTFail("Should throw GenerateContentError.internalError; no error thrown.")
527-
} catch let GenerateContentError.internalError(error as RPCError) {
527+
} catch let GenerateContentError.internalError(error as BackendError) {
528528
XCTAssertEqual(error.httpResponseCode, expectedStatusCode)
529529
XCTAssertEqual(error.status, .permissionDenied)
530530
XCTAssertTrue(error.message
@@ -607,7 +607,7 @@ final class GenerativeModelTests: XCTestCase {
607607
do {
608608
_ = try await model.generateContent(testPrompt)
609609
XCTFail("Should throw GenerateContentError.internalError; no error thrown.")
610-
} catch let GenerateContentError.internalError(underlying: rpcError as RPCError) {
610+
} catch let GenerateContentError.internalError(underlying: rpcError as BackendError) {
611611
XCTAssertEqual(rpcError.status, .invalidArgument)
612612
XCTAssertEqual(rpcError.httpResponseCode, expectedStatusCode)
613613
XCTAssertEqual(rpcError.message, "Request contains an invalid argument.")
@@ -706,7 +706,7 @@ final class GenerativeModelTests: XCTestCase {
706706
do {
707707
_ = try await model.generateContent(testPrompt)
708708
XCTFail("Should throw GenerateContentError.internalError; no error thrown.")
709-
} catch let GenerateContentError.internalError(underlying: rpcError as RPCError) {
709+
} catch let GenerateContentError.internalError(underlying: rpcError as BackendError) {
710710
XCTAssertEqual(rpcError.status, .notFound)
711711
XCTAssertEqual(rpcError.httpResponseCode, expectedStatusCode)
712712
XCTAssertTrue(rpcError.message.hasPrefix("models/unknown is not found"))
@@ -849,7 +849,7 @@ final class GenerativeModelTests: XCTestCase {
849849
for try await _ in stream {
850850
XCTFail("No content is there, this shouldn't happen.")
851851
}
852-
} catch let GenerateContentError.internalError(error as RPCError) {
852+
} catch let GenerateContentError.internalError(error as BackendError) {
853853
XCTAssertEqual(error.httpResponseCode, 400)
854854
XCTAssertEqual(error.status, .invalidArgument)
855855
XCTAssertEqual(error.message, "API key not valid. Please pass a valid API key.")
@@ -873,7 +873,7 @@ final class GenerativeModelTests: XCTestCase {
873873
for try await _ in stream {
874874
XCTFail("No content is there, this shouldn't happen.")
875875
}
876-
} catch let GenerateContentError.internalError(error as RPCError) {
876+
} catch let GenerateContentError.internalError(error as BackendError) {
877877
XCTAssertEqual(error.httpResponseCode, expectedStatusCode)
878878
XCTAssertEqual(error.status, .permissionDenied)
879879
XCTAssertTrue(error.message
@@ -1190,7 +1190,7 @@ final class GenerativeModelTests: XCTestCase {
11901190
XCTAssertNotNil(content.text)
11911191
responseCount += 1
11921192
}
1193-
} catch let GenerateContentError.internalError(rpcError as RPCError) {
1193+
} catch let GenerateContentError.internalError(rpcError as BackendError) {
11941194
XCTAssertEqual(rpcError.httpResponseCode, 499)
11951195
XCTAssertEqual(rpcError.status, .cancelled)
11961196

@@ -1374,7 +1374,7 @@ final class GenerativeModelTests: XCTestCase {
13741374
do {
13751375
_ = try await model.countTokens("Why is the sky blue?")
13761376
XCTFail("Request should not have succeeded.")
1377-
} catch let rpcError as RPCError {
1377+
} catch let rpcError as BackendError {
13781378
XCTAssertEqual(rpcError.httpResponseCode, 404)
13791379
XCTAssertEqual(rpcError.status, .notFound)
13801380
XCTAssert(rpcError.message.hasPrefix("models/test-model-name is not found"))

0 commit comments

Comments
 (0)