-
Notifications
You must be signed in to change notification settings - Fork 0
[Fix] Notification 잘못된 요청 응답 시, 방어적 로직 작성 #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.daedan.festabook.data.model.response.festival | ||
|
|
||
| import kotlinx.serialization.SerialName | ||
| import kotlinx.serialization.Serializable | ||
|
|
||
| @Serializable | ||
| data class RegisteredFestivalNotificationResponse( | ||
| @SerialName("festivalNotificationId") | ||
| val festivalNotificationId: Long, | ||
| @SerialName("festivalId") | ||
| val festivalId: Long, | ||
| @SerialName("universityName") | ||
| val universityName: String, | ||
| @SerialName("festivalName") | ||
| val festivalName: String, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,6 @@ import com.daedan.festabook.domain.repository.FestivalNotificationRepository | |
| import dev.zacsweers.metro.AppScope | ||
| import dev.zacsweers.metro.ContributesBinding | ||
| import dev.zacsweers.metro.Inject | ||
| import timber.log.Timber | ||
|
|
||
| @ContributesBinding(AppScope::class) | ||
| @Inject | ||
|
|
@@ -20,43 +19,73 @@ class FestivalNotificationRepositoryImpl( | |
| private val festivalLocalDataSource: FestivalLocalDataSource, | ||
| ) : FestivalNotificationRepository { | ||
| override suspend fun saveFestivalNotification(): Result<Unit> { | ||
| val deviceId = deviceLocalDataSource.getDeviceId() | ||
| if (deviceId == null) { | ||
| Timber.e("${::FestivalNotificationRepositoryImpl.name}: DeviceId가 없습니다.") | ||
| return Result.failure(IllegalStateException()) | ||
| } | ||
| val festivalId = festivalLocalDataSource.getFestivalId() | ||
| val deviceId = | ||
| deviceLocalDataSource.getDeviceId() ?: return Result.failure( | ||
| IllegalArgumentException(NO_DEVICE_ID_EXCEPTION), | ||
| ) | ||
| val festivalId = | ||
| festivalLocalDataSource.getFestivalId() ?: return Result.failure( | ||
| IllegalArgumentException(NO_FESTIVAL_ID_EXCEPTION), | ||
| ) | ||
|
|
||
| val result = | ||
| festivalId?.let { | ||
| festivalNotificationDataSource | ||
| .saveFestivalNotification( | ||
| festivalId = it, | ||
| deviceId = deviceId, | ||
| ).toResult() | ||
| } | ||
| ?: throw IllegalArgumentException("${::FestivalNotificationRepositoryImpl.javaClass.simpleName}festivalId가 null 입니다.") | ||
| return result | ||
| .mapCatching { | ||
| return festivalNotificationDataSource | ||
| .saveFestivalNotification( | ||
| festivalId = festivalId, | ||
| deviceId = deviceId, | ||
| ).toResult() | ||
| .mapCatching { response -> | ||
| festivalNotificationLocalDataSource.saveFestivalNotificationId( | ||
| festivalId, | ||
| it.festivalNotificationId, | ||
| response.festivalNotificationId, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| override suspend fun deleteFestivalNotification(): Result<Unit> { | ||
| val festivalId = | ||
| festivalLocalDataSource.getFestivalId() ?: return Result.failure( | ||
| IllegalStateException(), | ||
| ) | ||
| festivalLocalDataSource.getFestivalId() | ||
| ?: return Result.failure(IllegalStateException(NO_FESTIVAL_ID_EXCEPTION)) | ||
| val festivalNotificationId = | ||
| festivalNotificationLocalDataSource.getFestivalNotificationId(festivalId) | ||
| val response = | ||
| festivalNotificationDataSource.deleteFestivalNotification(festivalNotificationId) | ||
| festivalNotificationLocalDataSource.deleteFestivalNotificationId(festivalId) | ||
| return festivalNotificationDataSource | ||
| .deleteFestivalNotification(festivalNotificationId) | ||
| .toResult() | ||
| .mapCatching { | ||
| festivalNotificationLocalDataSource.deleteFestivalNotificationId(festivalId) | ||
| } | ||
| } | ||
|
|
||
| override suspend fun syncFestivalNotificationIsAllow(): Result<Boolean> { | ||
| val deviceId = | ||
| deviceLocalDataSource.getDeviceId() ?: return Result.failure( | ||
| IllegalArgumentException(NO_DEVICE_ID_EXCEPTION), | ||
| ) | ||
| val festivalId = | ||
| festivalLocalDataSource.getFestivalId() ?: return Result.failure( | ||
| IllegalArgumentException(NO_FESTIVAL_ID_EXCEPTION), | ||
| ) | ||
|
Comment on lines
+58
to
+66
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분도 로그 찍어놓으면 좋을 것 같아서 현재 KMP 코드에서 제가 run으로 해놨는데 어떻게 생각하시나용? |
||
|
|
||
| return response.toResult() | ||
| return festivalNotificationDataSource | ||
| .getFestivalNotification(deviceId) | ||
| .toResult() | ||
| .mapCatching { response -> | ||
| val notificationId = | ||
| response.find { it.festivalId == festivalId }?.festivalNotificationId | ||
| val isSubscribed = notificationId != null | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| festivalNotificationLocalDataSource.saveFestivalNotificationIsAllowed( | ||
| festivalId, | ||
| isSubscribed, | ||
| ) | ||
| if (isSubscribed) { | ||
| festivalNotificationLocalDataSource.saveFestivalNotificationId( | ||
| festivalId, | ||
| notificationId, | ||
| ) | ||
| } else { | ||
| festivalNotificationLocalDataSource.deleteFestivalNotificationId(festivalId) | ||
| } | ||
| isSubscribed | ||
| } | ||
| } | ||
|
|
||
| override fun getFestivalNotificationIsAllow(): Boolean { | ||
|
|
@@ -72,4 +101,11 @@ class FestivalNotificationRepositoryImpl( | |
| ) | ||
| } | ||
| } | ||
|
|
||
| companion object { | ||
| private val NO_FESTIVAL_ID_EXCEPTION = | ||
| "${::FestivalNotificationRepositoryImpl.name}: FestivalId가 없습니다." | ||
| private val NO_DEVICE_ID_EXCEPTION = | ||
| "${::FestivalNotificationRepositoryImpl.name}: DeviceId가 없습니다." | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,6 +44,16 @@ class SettingViewModel( | |
|
|
||
| val success = _success.asSharedFlow() | ||
|
|
||
| init { | ||
| viewModelScope.launch { | ||
| festivalNotificationRepository | ||
| .syncFestivalNotificationIsAllow() | ||
| .onSuccess { | ||
| _isAllowed.emit(it) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. _isAllowed.value = itemit 말고 이렇게 즉시 setter해주는건 어떤가용? |
||
| } | ||
| } | ||
| } | ||
|
|
||
| fun notificationAllowClick() { | ||
| if (!_isAllowed.value) { | ||
| viewModelScope.launch { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저 이해가 안간 부분이 있습니다.
PR 본문의 내용과 관련된 코드가 이 부분 같은데 이 코드는 서버에서 삭제를 '실패'했을 때가 아니라 성공 했을 때 로컬 데이터 소스에 삭제를 요청하는게 아닌가용?