Skip to content

Commit a4c1017

Browse files
authored
[#259] 공급자 링크 시 서로 다른 이메일로 연결을 시도할 경우 에러가 아닌 같은 이메일로 해야 한다는 안내문을 보이도록 개선한다 (#263)
* feat: 오류 분기 처리를 통해 이메일 관련 에러는 사용자에게 더 적합한 얼럿을 띄우도록 개선 * feat: 로그인 취소를 할 때 얼럿이 뜨지 않도록 추가 * style: switch문 케이스 수정
1 parent 7955722 commit a4c1017

3 files changed

Lines changed: 63 additions & 3 deletions

File tree

DevLog/Data/Common/DataLayerError.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import Foundation
1010
enum AuthError: Error {
1111
case notAuthenticated
1212
case failedToUnlinkLastProvider
13+
case linkEmailNotFound
14+
case linkEmailMismatch
15+
case linkCredentialAlreadyInUse
1316
case unsupportedProvider
1417
}
1518

DevLog/Data/Repository/AuthDataRepositoryImpl.swift

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,12 @@ final class AuthDataRepositoryImpl: AuthDataRepository {
5353
case .github:
5454
service = githubAuthService
5555
}
56-
57-
try await service.link(uid: uid, email: email)
56+
57+
do {
58+
try await service.link(uid: uid, email: email)
59+
} catch {
60+
throw mapLinkError(error)
61+
}
5862
}
5963

6064
func unlinkProvider(_ provider: AuthProvider) async throws {
@@ -80,3 +84,26 @@ final class AuthDataRepositoryImpl: AuthDataRepository {
8084
try await service.unlink(uid)
8185
}
8286
}
87+
88+
private extension AuthDataRepositoryImpl {
89+
func mapLinkError(_ error: Error) -> Error {
90+
if let emailFetchError = error as? EmailFetchError {
91+
switch emailFetchError {
92+
case .emailNotFound:
93+
return AuthError.linkEmailNotFound
94+
case .emailMismatch:
95+
return AuthError.linkEmailMismatch
96+
}
97+
}
98+
99+
let nsError = error as NSError
100+
if nsError.domain == AuthErrorDomain,
101+
let authErrorCode = AuthErrorCode(rawValue: nsError.code) {
102+
if authErrorCode == .credentialAlreadyInUse {
103+
return AuthError.linkCredentialAlreadyInUse
104+
}
105+
}
106+
107+
return error
108+
}
109+
}

DevLog/Presentation/ViewModel/AccountViewModel.swift

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ final class AccountViewModel: Store {
4040
}
4141

4242
enum AlertType {
43+
case linkEmailNotFound
44+
case linkEmailMismatch
45+
case linkCredentialAlreadyInUse
4346
case error
4447
}
4548

@@ -114,7 +117,8 @@ final class AccountViewModel: Store {
114117
let (currentProvider, allProviders) = try await fetchProvidersUseCase.execute()
115118
send(.updateProviders(currentProvider: currentProvider, allProviders: allProviders))
116119
} catch {
117-
send(.setAlert(isPresented: true, type: .error))
120+
if error.isSocialLoginCancelled { return }
121+
send(.setAlert(isPresented: true, type: linkAlertType(for: error)))
118122
}
119123
}
120124
case .unlink(let provider):
@@ -137,8 +141,34 @@ final class AccountViewModel: Store {
137141
}
138142

139143
private extension AccountViewModel {
144+
func linkAlertType(for error: Error) -> AlertType {
145+
guard let authError = error as? AuthError else {
146+
return .error
147+
}
148+
149+
switch authError {
150+
case .linkEmailNotFound:
151+
return .linkEmailNotFound
152+
case .linkEmailMismatch:
153+
return .linkEmailMismatch
154+
case .linkCredentialAlreadyInUse:
155+
return .linkCredentialAlreadyInUse
156+
case .notAuthenticated, .failedToUnlinkLastProvider, .unsupportedProvider:
157+
return .error
158+
}
159+
}
160+
140161
func setAlert(_ state: inout State, isPresented: Bool, type: AlertType?) {
141162
switch type {
163+
case .linkEmailNotFound:
164+
state.alertTitle = "이메일 확인 불가"
165+
state.alertMessage = "선택한 계정의 이메일 정보를 확인할 수 없어 연결할 수 없어요. 계정 설정을 확인한 뒤 다시 시도해주세요."
166+
case .linkEmailMismatch:
167+
state.alertTitle = "연결할 수 없음"
168+
state.alertMessage = "현재 로그인한 계정과 선택한 계정의 이메일이 달라 연결할 수 없어요. 같은 이메일의 계정으로 다시 시도해주세요."
169+
case .linkCredentialAlreadyInUse:
170+
state.alertTitle = "이미 연결된 계정"
171+
state.alertMessage = "선택한 계정은 이미 다른 계정에 연결되어 있어요. 해당 계정으로 로그인한 뒤 이용해주세요."
142172
case .error:
143173
state.alertTitle = "오류"
144174
state.alertMessage = "문제가 발생했습니다. 잠시 후 다시 시도해주세요."

0 commit comments

Comments
 (0)