Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ninecraft.booket.core.common.constants

data class ErrorDialogSpec(
val message: String,
val buttonLabel: String,
val action: () -> Unit,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.ninecraft.booket.core.common.constants

enum class ErrorScope {
GLOBAL, LOGIN, BOOK_REGISTER, RECORD_REGISTER
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.ninecraft.booket.core.common.event

import com.ninecraft.booket.core.common.constants.ErrorDialogSpec
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.receiveAsFlow
import java.util.UUID

object ErrorEventHelper {
private val _errorEvent = Channel<ErrorEvent>(Channel.BUFFERED)
val errorEvent = _errorEvent.receiveAsFlow()

fun sendError(event: ErrorEvent) {
_errorEvent.trySend(event)
}
}

sealed interface ErrorEvent {
data class ShowDialog(
val spec: ErrorDialogSpec,
val key: String = UUID.randomUUID().toString(),
) : ErrorEvent
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.ninecraft.booket.core.common.utils

import com.ninecraft.booket.core.common.constants.ErrorDialogSpec
import com.ninecraft.booket.core.common.constants.ErrorScope
import com.ninecraft.booket.core.common.event.ErrorEvent
import com.ninecraft.booket.core.common.event.ErrorEventHelper
import com.ninecraft.booket.core.network.response.ErrorResponse
import com.orhanobut.logger.Logger
import kotlinx.serialization.SerializationException
Expand Down Expand Up @@ -39,6 +43,58 @@ fun handleException(
}
}

fun postErrorDialog(
errorScope: ErrorScope,
exception: Throwable,
action: () -> Unit = {},
) {
val spec = buildDialog(
scope = errorScope,
exception = exception,
action = action,
)

ErrorEventHelper.sendError(event = ErrorEvent.ShowDialog(spec))
}

private fun buildDialog(
scope: ErrorScope,
exception: Throwable,
action: () -> Unit,
): ErrorDialogSpec {
val message = when {
exception.isNetworkError() -> {
"네트워크 연결이 불안정합니다.\n인터넷 연결을 확인해주세요"
}

exception is HttpException -> {
when (scope) {
ErrorScope.GLOBAL -> {
"알 수 없는 문제가 발생했어요.\n다시 시도해주세요"
}

ErrorScope.LOGIN -> {
"예기치 않은 오류가 발생했습니다.\n다시 로그인 해주세요."
}

ErrorScope.BOOK_REGISTER -> {
"도서 등록 중 오류가 발생했어요.\n다시 시도해주세요"
}

ErrorScope.RECORD_REGISTER -> {
"기록 저장에 실패했어요.\n다시 시도해주세요"
}
}
}

else -> {
"알 수 없는 문제가 발생했어요.\n다시 시도해주세요"
}
}

return ErrorDialogSpec(message = message, buttonLabel = "확인", action = action)
}

@Suppress("TooGenericExceptionCaught")
private fun HttpException.parseErrorMessage(): String? {
return try {
Expand Down Expand Up @@ -69,7 +125,7 @@ private fun getHttpErrorMessage(statusCode: Int): String {
}
}

private fun Throwable.isNetworkError(): Boolean {
fun Throwable.isNetworkError(): Boolean {
return this is UnknownHostException ||
this is ConnectException ||
this is SocketTimeoutException ||
Expand Down
1 change: 1 addition & 0 deletions core/ui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ android {
dependencies {
implementations(
projects.core.designsystem,
projects.core.common,

libs.compose.keyboard.state,
libs.logger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import com.ninecraft.booket.core.designsystem.theme.ReedTheme

@Composable
fun ReedDialog(
title: String,
confirmButtonText: String,
onConfirmRequest: () -> Unit,
modifier: Modifier = Modifier,
title: String? = null,
description: String? = null,
dismissButtonText: String? = null,
onDismissRequest: () -> Unit = {},
Expand Down Expand Up @@ -63,14 +63,16 @@ fun ReedDialog(
it()
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing6))
}
Text(
text = title,
color = ReedTheme.colors.contentPrimary,
textAlign = TextAlign.Center,
style = ReedTheme.typography.headline1SemiBold,
)
description?.let {
title?.let {
Text(
text = title,
color = ReedTheme.colors.contentPrimary,
textAlign = TextAlign.Center,
style = ReedTheme.typography.headline1SemiBold,
)
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing2))
}
description?.let {
Text(
text = description,
color = ReedTheme.colors.contentSecondary,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.ninecraft.booket.core.ui.component

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import com.ninecraft.booket.core.common.utils.isNetworkError
import com.ninecraft.booket.core.designsystem.ComponentPreview
import com.ninecraft.booket.core.designsystem.component.button.ReedButton
import com.ninecraft.booket.core.designsystem.component.button.ReedButtonColorStyle
import com.ninecraft.booket.core.designsystem.component.button.mediumButtonStyle
import com.ninecraft.booket.core.designsystem.theme.ReedTheme
import com.ninecraft.booket.core.ui.R

@Composable
fun ReedErrorUi(
exception: Throwable,
onRetryClick: () -> Unit,
) {
val message = if (exception.isNetworkError()) stringResource(R.string.network_error_message) else stringResource(R.string.server_error_message)
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(
text = message,
color = ReedTheme.colors.contentSecondary,
textAlign = TextAlign.Center,
style = ReedTheme.typography.body1Medium,
)
Spacer(modifier = Modifier.height(ReedTheme.spacing.spacing6))
ReedButton(
onClick = { onRetryClick() },
text = stringResource(R.string.retry),
colorStyle = ReedButtonColorStyle.PRIMARY,
sizeStyle = mediumButtonStyle,
)
}
}
}

@ComponentPreview
@Composable
private fun ReedNetworkErrorUiPreview() {
ReedErrorUi(
exception = java.io.IOException("네트워크 오류"),
onRetryClick = {},
)
}

@ComponentPreview
@Composable
private fun ReedServerErrorUiPreview() {
ReedErrorUi(
exception = Exception("알 수 없는 문제"),
onRetryClick = {},
)
}
2 changes: 2 additions & 0 deletions core/ui/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
<resources>
<string name="no_more_result">더 이상 결과가 없습니다</string>
<string name="retry">다시 시도</string>
<string name="network_error_message">네트워크 연결이 불안정합니다.\n인터넷 연결을 확인해주세요</string>
<string name="server_error_message">알 수 없는 문제가 발생했어요.\n다시 시도해주세요</string>
</resources>
Loading
Loading