Skip to content

Commit f075b87

Browse files
committed
fix: Show clear alert for expired AWS tokens
- Update error handling in BackendModel to detect expired token errors by checking if error.localizedDescription contains "expired". - Set a specific alert message ("Your AWS credentials have expired. Please log in again.") when an expired token is detected. - This change replaces the generic "BedrockError error 0" message with a clear re-login prompt.
1 parent 39a45c4 commit f075b87

File tree

2 files changed

+40
-48
lines changed

2 files changed

+40
-48
lines changed

Amazon Bedrock Client for Mac/Managers/BedrockClient.swift

+27-15
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ class BackendModel: ObservableObject {
3232
self.backend = try BackendModel.createBackend()
3333
logger.info("Backend initialized successfully")
3434
} catch {
35-
logger.error(
36-
"Failed to initialize Backend: \(error.localizedDescription). Using fallback Backend."
37-
)
35+
logger.error("Failed to initialize Backend: \(error.localizedDescription). Using fallback Backend.")
3836
self.backend = Backend.fallbackInstance()
39-
alertMessage =
40-
"Backend initialization failed: \(error.localizedDescription). Using fallback settings."
37+
if error.localizedDescription.lowercased().contains("expired") {
38+
alertMessage = "Your AWS credentials have expired. Please log in again."
39+
} else {
40+
alertMessage = "Backend initialization failed: \(error.localizedDescription). Using fallback settings."
41+
}
4142
}
4243
setupObservers()
4344
}
@@ -489,29 +490,23 @@ class Backend: Equatable {
489490
maxResults: Int? = nil,
490491
nextToken: String? = nil,
491492
typeEquals: BedrockClientTypes.InferenceProfileType? = nil
492-
) async throws -> [BedrockClientTypes.InferenceProfileSummary] {
493+
) async -> [BedrockClientTypes.InferenceProfileSummary] {
493494
do {
494-
// Prepare the request input
495495
let input = AWSBedrock.ListInferenceProfilesInput(
496496
maxResults: maxResults,
497497
nextToken: nextToken,
498498
typeEquals: typeEquals
499499
)
500-
501-
// Execute the API call
502500
let response = try await self.bedrockClient.listInferenceProfiles(input: input)
503-
504-
// Validate and process the response
505501
guard let summaries = response.inferenceProfileSummaries else {
506502
logger.warning("No inference profiles found in the response.")
507503
return []
508504
}
509-
510505
logger.info("Fetched \(summaries.count) inference profiles.")
511506
return summaries
512507
} catch {
513508
logger.error("Failed to fetch inference profiles: \(error.localizedDescription)")
514-
throw BedrockError.invalidResponse(error.localizedDescription)
509+
return []
515510
}
516511
}
517512

@@ -1399,7 +1394,24 @@ enum BedrockRuntimeError: Error {
13991394
case decodingFailed
14001395
}
14011396
enum BedrockError: Error {
1397+
/// The response from Bedrock was invalid.
14021398
case invalidResponse(String?)
1403-
case genericError(String)
1404-
case tokenExpired
1399+
/// The AWS credentials have expired.
1400+
case expiredToken(String?)
1401+
/// An unknown error occurred.
1402+
case unknown(String?)
1403+
1404+
init(error: Error) {
1405+
if let awsError = error as? AWSClientRuntime.AWSServiceError {
1406+
if let typeName = awsError.typeName?.lowercased(), typeName.contains("expiredtoken") {
1407+
self = .expiredToken(awsError.message)
1408+
} else {
1409+
self = .unknown(awsError.message)
1410+
}
1411+
} else if let commonError = error as? AwsCommonRuntimeKit.CommonRunTimeError {
1412+
self = .invalidResponse(commonError.localizedDescription)
1413+
} else {
1414+
self = .unknown(error.localizedDescription)
1415+
}
1416+
}
14051417
}

Amazon Bedrock Client for Mac/Views/MainView.swift

+13-33
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import Logging
1414
struct MainView: View {
1515
@State private var selection: SidebarSelection? = .newChat
1616
@State private var menuSelection: SidebarSelection? = nil
17-
@State private var showAlert: Bool = false
18-
@State private var alertMessage: String = ""
1917
@State private var organizedChatModels: [String: [ChatModel]] = [:]
2018
@State private var isHovering = false
2119
@State private var alertInfo: AlertInfo?
@@ -42,7 +40,8 @@ struct MainView: View {
4240
.navigationTitle("")
4341
.onChange(of: backendModel.backend) { _ in
4442
fetchModels()
45-
}.onChange(of: selection) { newValue in
43+
}
44+
.onChange(of: selection) { newValue in
4645
if case .chat(let chat) = newValue {
4746
if !chatManager.chats.contains(where: { $0.chatId == chat.chatId }) {
4847
selection = .newChat
@@ -117,46 +116,27 @@ struct MainView: View {
117116
}
118117

119118
private func handleFetchModelsError(_ error: Error) {
120-
if let awsError = error as? AWSClientRuntime.AWSServiceError {
121-
let errorType = awsError.typeName ?? "Unknown AWS Error"
122-
var errorMessage = awsError.message ?? "No error message provided"
123-
124-
if errorType == "ExpiredTokenException" {
125-
errorMessage += "\nPlease log in again."
126-
}
127-
119+
let bedrockError = BedrockError(error: error)
120+
switch bedrockError {
121+
case .expiredToken(let message):
128122
self.alertInfo = AlertInfo(
129-
title: "\(errorType)",
130-
message: errorMessage
123+
title: "Expired Token",
124+
message: message ?? "Your AWS credentials have expired. Please log in again."
131125
)
132-
} else if let crtError = error as? AwsCommonRuntimeKit.CRTError {
126+
case .invalidResponse(let message):
133127
self.alertInfo = AlertInfo(
134-
title: "CRT Error",
135-
message: "Code: \(crtError.code), Message: \(crtError.message)"
128+
title: "Invalid Response",
129+
message: message ?? "The response from Bedrock was invalid."
136130
)
137-
} else if let commonRunTimeError = error as? AwsCommonRuntimeKit.CommonRunTimeError {
138-
self.alertInfo = AlertInfo(
139-
title: "CommonRunTime Error",
140-
message: "Error: \(commonRunTimeError)"
141-
)
142-
} else {
143-
// 알 수 없는 에러 타입에 대한 더 자세한 정보 제공
131+
case .unknown(let message):
144132
self.alertInfo = AlertInfo(
145133
title: "Unknown Error",
146-
message: "Type: \(type(of: error)), Description: \(error.localizedDescription)"
134+
message: message ?? "An unknown error occurred."
147135
)
148136
}
149-
150-
// 로깅 추가
137+
logger.error("Fetch Models Error - \(self.alertInfo?.title ?? "Error"): \(self.alertInfo?.message ?? "No message")")
151138
print("Error type: \(type(of: error))")
152139
print("Error description: \(error)")
153-
154-
if let alertInfo = self.alertInfo {
155-
logger.error("Fetch Models Error - \(alertInfo.title): \(alertInfo.message)")
156-
} else {
157-
logger.error("Fetch Models Error occurred, but alertInfo is nil")
158-
}
159-
logger.error("Error details: \(String(describing: error))")
160140
}
161141

162142
private func selectDefaultModel() {

0 commit comments

Comments
 (0)