Skip to content

Commit

Permalink
Merge pull request #324 from mash-up-kr/feature/#287
Browse files Browse the repository at this point in the history
[#287] ๊ทธ๋ฃน์›์ด ๋‹ค ์ฐฌ ๋ฐฉ์— ๋“ค์–ด๊ฐ”์„ ๋•Œ, ๋‹ค ์ฐผ๋‹ค๊ณ  ์—๋Ÿฌ ๋ช…์‹œ
  • Loading branch information
oreocube authored Sep 30, 2024
2 parents 5cc8a93 + 2b47e90 commit a6bbdaf
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.mashup.gabbangzip.sharedalbum.data.base

import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import okhttp3.ResponseBody
import retrofit2.HttpException

object PicApiErrorParser {
private val moshi = Moshi.Builder().build()

// PicResponse์˜ ํƒ€์ž…์„ ๋™์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ParameterizedType ์ƒ์„ฑ
private val type = Types.newParameterizedType(PicResponse::class.java, Any::class.java)
private val adapter = moshi.adapter<PicResponse<Any>>(type)

fun parse(e: Throwable): Throwable {
return when (e) {
is HttpException -> {
val error = e.response()
?.errorBody()
?.let { parseErrorResponse(it) }
PicApiException(error)
}

else -> e
}
}

private fun parseErrorResponse(errorResponseBody: ResponseBody): PicErrorResponse? {
return try {
val response = adapter.fromJson(errorResponseBody.string())
if (response != null && !response.isSuccess) {
response.errorResponse
} else {
null
}
} catch (e: Exception) {
null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,19 @@ data class PicErrorResponse(
val message: String,
)

data class PicApiException(
val errorResponse: PicErrorResponse?,
) : RuntimeException() {
override val message: String
get() = errorResponse?.message.orEmpty()
}

suspend fun <T> callApi(
execute: suspend () -> PicResponse<T>,
): T {
return execute().data ?: throw IllegalStateException()
return runCatching {
execute().data ?: throw NoSuchElementException()
}.getOrElse { e ->
throw PicApiErrorParser.parse(e)
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.mashup.gabbangzip.sharedalbum.data.repository

import com.mashup.gabbangzip.sharedalbum.data.base.PicApiException
import com.mashup.gabbangzip.sharedalbum.data.base.callApi
import com.mashup.gabbangzip.sharedalbum.data.common.toS3Url
import com.mashup.gabbangzip.sharedalbum.data.dto.request.CreateGroupRequest
import com.mashup.gabbangzip.sharedalbum.data.dto.request.EnterGroupRequest
import com.mashup.gabbangzip.sharedalbum.data.dto.response.group.toDomainModel
import com.mashup.gabbangzip.sharedalbum.data.service.GroupService
import com.mashup.gabbangzip.sharedalbum.domain.base.PicException
import com.mashup.gabbangzip.sharedalbum.domain.model.GroupParam
import com.mashup.gabbangzip.sharedalbum.domain.model.group.GroupDomainModel
import com.mashup.gabbangzip.sharedalbum.domain.model.group.GroupInfoDomainModel
Expand Down Expand Up @@ -37,7 +39,19 @@ class GroupRepositoryImpl @Inject constructor(

override suspend fun enterGroupByCode(code: String): Long {
val request = EnterGroupRequest(code)
return callApi { groupService.enterGroupByCode(request) }.groupId
return runCatching {
callApi { groupService.enterGroupByCode(request) }.groupId
}.getOrElse { e ->
throw if (e is PicApiException && e.errorResponse != null) {
when (e.errorResponse.code) {
CODE_NOT_EXIST -> PicException.InvalidGroupCodeException
CODE_ARGUMENT_NOT_VALID -> PicException.GroupOverflowException
else -> e
}
} else {
e
}
}
}

override suspend fun getGroupList(): List<GroupDomainModel> {
Expand All @@ -55,4 +69,9 @@ class GroupRepositoryImpl @Inject constructor(
override suspend fun withdrawGroup(groupId: Long): WithdrawalGroupDomainModel {
return callApi { groupService.withdrawGroup(groupId) }.toDomainModel()
}

companion object {
private const val CODE_NOT_EXIST = "C001_NOT_EXIST"
private const val CODE_ARGUMENT_NOT_VALID = "C009_ARGUMENT_NOT_VALID"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ package com.mashup.gabbangzip.sharedalbum.domain.base
sealed class PicException : Throwable() {
data object LoginRequiredException : PicException()
data object UnknownException : PicException()
data object GroupOverflowException : PicException()
data object InvalidGroupCodeException : PicException()
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.mashup.gabbangzip.sharedalbum.presentation.R
import com.mashup.gabbangzip.sharedalbum.presentation.theme.SharedAlbumTheme
import com.mashup.gabbangzip.sharedalbum.presentation.ui.common.PicSnackbarHost
import com.mashup.gabbangzip.sharedalbum.presentation.ui.common.model.PicSnackbarType
Expand Down Expand Up @@ -59,11 +58,13 @@ class InvitationCodeActivity : ComponentActivity() {
when (state.isInvitationSuccessful) {
true -> navigateToMainActivity()
false -> {
LaunchedEffect(snackbarHostState) {
snackbarHostState.showPicSnackbar(
type = PicSnackbarType.WARNING,
message = getString(R.string.enter_group_by_code_failure_message),
)
LaunchedEffect(state.errorMessageRes) {
state.errorMessageRes?.let { message ->
snackbarHostState.showPicSnackbar(
type = PicSnackbarType.WARNING,
message = getString(message),
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.mashup.gabbangzip.sharedalbum.presentation.ui.invitation

import androidx.annotation.StringRes

data class InvitationCodeUiState(
val isLoading: Boolean = false,
val isInvitationSuccessful: Boolean? = null,
@StringRes val errorMessageRes: Int? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package com.mashup.gabbangzip.sharedalbum.presentation.ui.invitation

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.mashup.gabbangzip.sharedalbum.domain.base.PicException
import com.mashup.gabbangzip.sharedalbum.domain.usecase.invitation.EnterGroupByInvitationCodeUseCase
import com.mashup.gabbangzip.sharedalbum.presentation.R
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand All @@ -21,7 +23,7 @@ class InvitationCodeViewModel @Inject constructor(
_uiState.update { state ->
state.copy(
isLoading = true,
isInvitationSuccessful = null,
errorMessageRes = null,
)
}
viewModelScope.launch {
Expand All @@ -39,9 +41,18 @@ class InvitationCodeViewModel @Inject constructor(
state.copy(
isLoading = false,
isInvitationSuccessful = false,
errorMessageRes = mapErrorMessageRes(e),
)
}
}
}
}

private fun mapErrorMessageRes(e: Throwable): Int {
return when (e) {
is PicException.InvalidGroupCodeException -> R.string.enter_group_by_code_failure_not_found
is PicException.GroupOverflowException -> R.string.enter_group_by_code_failure_overflow
else -> R.string.error_network
}
}
}
3 changes: 2 additions & 1 deletion presentation/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@
<string name="enter_group_by_code_title">๊ทธ๋ฃน ๋“ค์–ด๊ฐ€๊ธฐ</string>
<string name="enter_group_by_code_input_title">์ดˆ๋Œ€์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”</string>
<string name="enter_group_by_code_input_hint">์˜ˆ) A12B0EHQ</string>
<string name="enter_group_by_code_failure_message">์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ดˆ๋Œ€์ฝ”๋“œ์—์š”.</string>
<string name="enter_group_by_code_failure_not_found">์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ดˆ๋Œ€์ฝ”๋“œ์—์š”.</string>
<string name="enter_group_by_code_failure_overflow">๊ทธ๋ฃน์ด ๊ฐ€๋“ ์ฐผ์–ด์š”.</string>

<string name="vote_complete_title">๋‚ด PIC์„ ๊ณจ๋ž์–ด์š”!</string>
<string name="vote_complete_subtitle">๋ชจ๋“  ์‚ฌ๋žŒ์ด PIC์„ ์™„๋ฃŒํ•˜๋ฉด\n๋„ค์ปท ์‚ฌ์ง„์ด ๋งŒ๋“ค์–ด์ ธ์š”</string>
Expand Down

0 comments on commit a6bbdaf

Please sign in to comment.