Skip to content

Commit 1a4ba6f

Browse files
authored
Merge pull request #118 from YAPP-Github/BOOK-233-feature/#117
feat: 에러 핸들링 및 공통 UI 처리
2 parents ecbfa0b + 5f94120 commit 1a4ba6f

File tree

32 files changed

+611
-424
lines changed

32 files changed

+611
-424
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.ninecraft.booket.core.common.constants
2+
3+
data class ErrorDialogSpec(
4+
val message: String,
5+
val buttonLabel: String,
6+
val action: () -> Unit,
7+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.ninecraft.booket.core.common.constants
2+
3+
enum class ErrorScope {
4+
GLOBAL, LOGIN, BOOK_REGISTER, RECORD_REGISTER
5+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.ninecraft.booket.core.common.event
2+
3+
import com.ninecraft.booket.core.common.constants.ErrorDialogSpec
4+
import kotlinx.coroutines.channels.Channel
5+
import kotlinx.coroutines.flow.receiveAsFlow
6+
import java.util.UUID
7+
8+
object ErrorEventHelper {
9+
private val _errorEvent = Channel<ErrorEvent>(Channel.BUFFERED)
10+
val errorEvent = _errorEvent.receiveAsFlow()
11+
12+
fun sendError(event: ErrorEvent) {
13+
_errorEvent.trySend(event)
14+
}
15+
}
16+
17+
sealed interface ErrorEvent {
18+
data class ShowDialog(
19+
val spec: ErrorDialogSpec,
20+
val key: String = UUID.randomUUID().toString(),
21+
) : ErrorEvent
22+
}

core/common/src/main/kotlin/com/ninecraft/booket/core/common/utils/HandleException.kt

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package com.ninecraft.booket.core.common.utils
22

3+
import com.ninecraft.booket.core.common.constants.ErrorDialogSpec
4+
import com.ninecraft.booket.core.common.constants.ErrorScope
5+
import com.ninecraft.booket.core.common.event.ErrorEvent
6+
import com.ninecraft.booket.core.common.event.ErrorEventHelper
37
import com.ninecraft.booket.core.network.response.ErrorResponse
48
import com.orhanobut.logger.Logger
59
import kotlinx.serialization.SerializationException
@@ -39,6 +43,58 @@ fun handleException(
3943
}
4044
}
4145

46+
fun postErrorDialog(
47+
errorScope: ErrorScope,
48+
exception: Throwable,
49+
action: () -> Unit = {},
50+
) {
51+
val spec = buildDialog(
52+
scope = errorScope,
53+
exception = exception,
54+
action = action,
55+
)
56+
57+
ErrorEventHelper.sendError(event = ErrorEvent.ShowDialog(spec))
58+
}
59+
60+
private fun buildDialog(
61+
scope: ErrorScope,
62+
exception: Throwable,
63+
action: () -> Unit,
64+
): ErrorDialogSpec {
65+
val message = when {
66+
exception.isNetworkError() -> {
67+
"네트워크 연결이 불안정합니다.\n인터넷 연결을 확인해주세요"
68+
}
69+
70+
exception is HttpException -> {
71+
when (scope) {
72+
ErrorScope.GLOBAL -> {
73+
"알 수 없는 문제가 발생했어요.\n다시 시도해주세요"
74+
}
75+
76+
ErrorScope.LOGIN -> {
77+
"예기치 않은 오류가 발생했습니다.\n다시 로그인 해주세요."
78+
}
79+
80+
ErrorScope.BOOK_REGISTER -> {
81+
"도서 등록 중 오류가 발생했어요.\n다시 시도해주세요"
82+
}
83+
84+
ErrorScope.RECORD_REGISTER -> {
85+
"기록 저장에 실패했어요.\n다시 시도해주세요"
86+
}
87+
}
88+
}
89+
90+
else -> {
91+
"알 수 없는 문제가 발생했어요.\n다시 시도해주세요"
92+
}
93+
}
94+
95+
return ErrorDialogSpec(message = message, buttonLabel = "확인", action = action)
96+
}
97+
4298
@Suppress("TooGenericExceptionCaught")
4399
private fun HttpException.parseErrorMessage(): String? {
44100
return try {
@@ -69,7 +125,7 @@ private fun getHttpErrorMessage(statusCode: Int): String {
69125
}
70126
}
71127

72-
private fun Throwable.isNetworkError(): Boolean {
128+
fun Throwable.isNetworkError(): Boolean {
73129
return this is UnknownHostException ||
74130
this is ConnectException ||
75131
this is SocketTimeoutException ||

core/ui/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ android {
1212
dependencies {
1313
implementations(
1414
projects.core.designsystem,
15+
projects.core.common,
1516

1617
libs.compose.keyboard.state,
1718
libs.logger,

core/ui/src/main/kotlin/com/ninecraft/booket/core/ui/component/ReedDialog.kt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ import com.ninecraft.booket.core.designsystem.theme.ReedTheme
2424

2525
@Composable
2626
fun ReedDialog(
27-
title: String,
2827
confirmButtonText: String,
2928
onConfirmRequest: () -> Unit,
3029
modifier: Modifier = Modifier,
30+
title: String? = null,
3131
description: String? = null,
3232
dismissButtonText: String? = null,
3333
onDismissRequest: () -> Unit = {},
@@ -63,14 +63,16 @@ fun ReedDialog(
6363
it()
6464
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing6))
6565
}
66-
Text(
67-
text = title,
68-
color = ReedTheme.colors.contentPrimary,
69-
textAlign = TextAlign.Center,
70-
style = ReedTheme.typography.headline1SemiBold,
71-
)
72-
description?.let {
66+
title?.let {
67+
Text(
68+
text = title,
69+
color = ReedTheme.colors.contentPrimary,
70+
textAlign = TextAlign.Center,
71+
style = ReedTheme.typography.headline1SemiBold,
72+
)
7373
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
74+
}
75+
description?.let {
7476
Text(
7577
text = description,
7678
color = ReedTheme.colors.contentSecondary,
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.ninecraft.booket.core.ui.component
2+
3+
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Spacer
6+
import androidx.compose.foundation.layout.fillMaxSize
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.material3.Text
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.ui.Alignment
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.res.stringResource
13+
import androidx.compose.ui.text.style.TextAlign
14+
import com.ninecraft.booket.core.common.utils.isNetworkError
15+
import com.ninecraft.booket.core.designsystem.ComponentPreview
16+
import com.ninecraft.booket.core.designsystem.component.button.ReedButton
17+
import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle
18+
import com.ninecraft.booket.core.designsystem.component.button.mediumButtonStyle
19+
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
20+
import com.ninecraft.booket.core.ui.R
21+
22+
@Composable
23+
fun ReedErrorUi(
24+
exception: Throwable,
25+
onRetryClick: () -> Unit,
26+
) {
27+
val message = if (exception.isNetworkError()) stringResource(R.string.network_error_message) else stringResource(R.string.server_error_message)
28+
Box(
29+
modifier = Modifier.fillMaxSize(),
30+
contentAlignment = Alignment.Center,
31+
) {
32+
Column(horizontalAlignment = Alignment.CenterHorizontally) {
33+
Text(
34+
text = message,
35+
color = ReedTheme.colors.contentSecondary,
36+
textAlign = TextAlign.Center,
37+
style = ReedTheme.typography.body1Medium,
38+
)
39+
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing6))
40+
ReedButton(
41+
onClick = { onRetryClick() },
42+
text = stringResource(R.string.retry),
43+
colorStyle = ReedButtonColorStyle.PRIMARY,
44+
sizeStyle = mediumButtonStyle,
45+
)
46+
}
47+
}
48+
}
49+
50+
@ComponentPreview
51+
@Composable
52+
private fun ReedNetworkErrorUiPreview() {
53+
ReedErrorUi(
54+
exception = java.io.IOException("네트워크 오류"),
55+
onRetryClick = {},
56+
)
57+
}
58+
59+
@ComponentPreview
60+
@Composable
61+
private fun ReedServerErrorUiPreview() {
62+
ReedErrorUi(
63+
exception = Exception("알 수 없는 문제"),
64+
onRetryClick = {},
65+
)
66+
}

core/ui/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
<resources>
33
<string name="no_more_result">더 이상 결과가 없습니다</string>
44
<string name="retry">다시 시도</string>
5+
<string name="network_error_message">네트워크 연결이 불안정합니다.\n인터넷 연결을 확인해주세요</string>
6+
<string name="server_error_message">알 수 없는 문제가 발생했어요.\n다시 시도해주세요</string>
57
</resources>

0 commit comments

Comments
 (0)