Skip to content

Commit ebb040e

Browse files
committed
fix: T MAP 경로 검색 결과가 존재 하지 않는 경우 에러 처리
1 parent 8269d37 commit ebb040e

File tree

11 files changed

+85
-40
lines changed

11 files changed

+85
-40
lines changed

data/src/main/java/com/stop/data/remote/ResultCall.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,17 @@ internal class ResultCall<T : Any>(private val call: Call<T>) : Call<NetworkResu
4747
this@ResultCall,
4848
Response.success(NetworkResult.Success(responseBody))
4949
)
50-
} else {
51-
callback.onResponse(
52-
this@ResultCall,
53-
Response.success(
54-
NetworkResult.Failure(
55-
response.code(),
56-
response.errorBody()?.string()
57-
)
50+
return
51+
}
52+
callback.onResponse(
53+
this@ResultCall,
54+
Response.success(
55+
NetworkResult.Failure(
56+
response.code(),
57+
response.errorBody()?.string()
5858
)
5959
)
60-
}
60+
)
6161
}
6262

6363
override fun onFailure(call: Call<T>, t: Throwable) {

data/src/main/java/com/stop/data/remote/source/route/RouteRemoteDataSourceImpl.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.stop.data.remote.source.route
22

3+
import com.squareup.moshi.JsonDataException
34
import com.stop.data.remote.model.NetworkResult
45
import com.stop.data.remote.network.ApisDataService
56
import com.stop.data.remote.network.OpenApiSeoulService
@@ -30,7 +31,11 @@ internal class RouteRemoteDataSourceImpl @Inject constructor(
3031
tMapApiService.getRoutes(routeRequest.toMap())
3132
) {
3233
return when (this) {
33-
is NetworkResult.Success -> eraseDuplicateLeg(this.data.metaData.plan.itineraries)
34+
is NetworkResult.Success -> {
35+
val itineraries = this.data.metaData?.plan?.itineraries
36+
?: throw JsonDataException(NO_ROUTE_RESULT)
37+
eraseDuplicateLeg(itineraries)
38+
}
3439
is NetworkResult.Failure -> throw IllegalArgumentException(this.message)
3540
is NetworkResult.NetworkError -> throw this.exception
3641
is NetworkResult.Unexpected -> throw this.exception
@@ -242,5 +247,6 @@ internal class RouteRemoteDataSourceImpl @Inject constructor(
242247

243248
companion object {
244249
private const val NO_SUBWAY_STATION = "해당하는 지하철역이 없습니다."
250+
private const val NO_ROUTE_RESULT = "경로 검색 결과가 없습니다."
245251
}
246252
}

data/src/main/java/com/stop/data/repository/RouteRepositoryImpl.kt

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.stop.data.repository
22

3+
import com.squareup.moshi.JsonDataException
34
import com.stop.data.remote.source.route.RouteRemoteDataSource
45
import com.stop.domain.model.geoLocation.AddressType
56
import com.stop.domain.model.nowlocation.SubwayRouteLocationUseCaseItem
@@ -21,7 +22,11 @@ internal class RouteRepositoryImpl @Inject constructor(
2122
) : RouteRepository {
2223

2324
override suspend fun getRoute(routeRequest: RouteRequest): List<Itinerary> {
24-
return remoteDataSource.getRoute(routeRequest)
25+
return try {
26+
remoteDataSource.getRoute(routeRequest)
27+
} catch (exception: JsonDataException) {
28+
listOf()
29+
}
2530
}
2631

2732
override suspend fun reverseGeocoding(
@@ -53,19 +58,23 @@ internal class RouteRepositoryImpl @Inject constructor(
5358
startSubwayStation: String,
5459
endSubwayStation: String
5560
): SubwayRouteLocationUseCaseItem {
56-
return remoteDataSource.getRoute(routeRequest).first {
57-
it.legs.any { leg ->
61+
return try {
62+
remoteDataSource.getRoute(routeRequest).first {
63+
it.legs.any { leg ->
64+
leg.mode == "SUBWAY"
65+
&& leg.route?.contains(subwayLine) ?: false
66+
&& leg.start.name.contains(startSubwayStation)
67+
&& leg.end.name.contains(endSubwayStation)
68+
}
69+
}.legs.first { leg ->
5870
leg.mode == "SUBWAY"
5971
&& leg.route?.contains(subwayLine) ?: false
6072
&& leg.start.name.contains(startSubwayStation)
6173
&& leg.end.name.contains(endSubwayStation)
62-
}
63-
}.legs.first { leg ->
64-
leg.mode == "SUBWAY"
65-
&& leg.route?.contains(subwayLine) ?: false
66-
&& leg.start.name.contains(startSubwayStation)
67-
&& leg.end.name.contains(endSubwayStation)
68-
}.toUseCaseModel()
74+
}.toUseCaseModel()
75+
} catch (exception: JsonDataException) {
76+
throw IllegalArgumentException("경로 검색 결과가 없습니다.")
77+
}
6978
}
7079

7180
override suspend fun getSeoulBusStationArsId(stationName: String): List<BusStationInfo> {

domain/src/main/java/com/stop/domain/model/route/tmap/origin/RouteResponse.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import com.squareup.moshi.JsonClass
44

55
@JsonClass(generateAdapter = true)
66
data class RouteResponse(
7-
val metaData: MetaData
7+
val metaData: MetaData?
88
)

domain/src/main/java/com/stop/domain/usecase/route/GetRouteUseCaseImpl.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ internal class GetRouteUseCaseImpl @Inject constructor(
1313
override suspend operator fun invoke(routeRequest: RouteRequest): List<Itinerary> {
1414
val originItineraries = routeRepository.getRoute(routeRequest)
1515

16+
if (originItineraries.isEmpty()) {
17+
return listOf()
18+
}
19+
1620
return originItineraries.fold(listOf()) itinerary@{ itineraries, itinerary ->
1721
val result = itinerary.legs.fold(listOf<Route>()) { routes, leg ->
1822
try {
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package com.stop.model
22

3-
enum class ErrorType {
4-
NO_START, NO_END,
3+
import com.stop.R
4+
5+
enum class ErrorType(val stringResourcesId: Int) {
6+
NO_START(R.string.no_start_input),
7+
NO_END(R.string.no_end_input),
8+
NO_ROUTE_RESULT(R.string.route_result_not_exist)
59
}

presentation/src/main/java/com/stop/ui/mission/MissionFragment.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import android.os.Bundle
77
import android.view.LayoutInflater
88
import android.view.View
99
import android.view.ViewGroup
10+
import android.widget.Toast
1011
import androidx.fragment.app.Fragment
1112
import androidx.fragment.app.viewModels
1213
import androidx.lifecycle.lifecycleScope
@@ -131,6 +132,14 @@ class MissionFragment : Fragment(), MissionHandler {
131132
})
132133
}
133134
}
135+
136+
viewModel.errorMessage.observe(viewLifecycleOwner) {
137+
it.getContentIfNotHandled()?.let { errorType ->
138+
val message = getString(errorType.stringResourcesId)
139+
140+
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
141+
}
142+
}
134143
}
135144

136145
private fun drawBusLocationLine() {

presentation/src/main/java/com/stop/ui/mission/MissionViewModel.kt

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import com.stop.domain.usecase.nowlocation.GetBusNowLocationUseCase
88
import com.stop.domain.usecase.nowlocation.GetNowStationLocationUseCase
99
import com.stop.domain.usecase.nowlocation.GetSubwayRouteUseCase
1010
import com.stop.domain.usecase.nowlocation.GetSubwayTrainNowStationUseCase
11+
import com.stop.model.ErrorType
12+
import com.stop.model.Event
1113
import com.stop.model.Location
1214
import dagger.hilt.android.lifecycle.HiltViewModel
1315
import kotlinx.coroutines.Dispatchers
@@ -39,6 +41,10 @@ class MissionViewModel @Inject constructor(
3941
val estimatedTimeRemaining: LiveData<Int>
4042
get() = _estimatedTimeRemaining
4143

44+
private val _errorMessage = MutableLiveData<Event<ErrorType>>()
45+
val errorMessage: LiveData<Event<ErrorType>>
46+
get() = _errorMessage
47+
4248
val leftMinute: LiveData<String> = Transformations.switchMap(estimatedTimeRemaining) {
4349
MutableLiveData<String>().apply {
4450
value = (it / TIME_UNIT).toString().padStart(TIME_DIGIT, '0')
@@ -132,17 +138,22 @@ class MissionViewModel @Inject constructor(
132138
private fun getSubwayRoute() {
133139
viewModelScope.launch {
134140
val startLocation = getNowStationLocation()
135-
this@MissionViewModel._subwayRoute.value = getSubwayRouteUseCase(
136-
RouteRequest(
137-
startLocation.longitude,
138-
startLocation.latitude,
139-
TEST_SUBWAY_LONG,
140-
TEST_SUBWAY_LAT
141-
),
142-
TEST_SUBWAY_NUMER.toString() + LINE,
143-
startSubwayStation.dropLast(1), //"역" 버리기
144-
TEST_END_SUBWAY_STATION
145-
)
141+
try {
142+
this@MissionViewModel._subwayRoute.value = getSubwayRouteUseCase(
143+
RouteRequest(
144+
startLocation.longitude,
145+
startLocation.latitude,
146+
TEST_SUBWAY_LONG,
147+
TEST_SUBWAY_LAT
148+
),
149+
TEST_SUBWAY_NUMER.toString() + LINE,
150+
startSubwayStation.dropLast(1), //"역" 버리기
151+
TEST_END_SUBWAY_STATION
152+
)
153+
} catch (exception: IllegalArgumentException) {
154+
_errorMessage.value = Event(ErrorType.NO_ROUTE_RESULT)
155+
return@launch
156+
}
146157
}
147158
}
148159

presentation/src/main/java/com/stop/ui/route/RouteFragment.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import androidx.navigation.fragment.navArgs
1212
import com.stop.R
1313
import com.stop.databinding.FragmentRouteBinding
1414
import com.stop.domain.model.route.tmap.custom.Itinerary
15-
import com.stop.model.ErrorType
1615
import dagger.hilt.android.AndroidEntryPoint
1716

1817
@AndroidEntryPoint
@@ -85,10 +84,7 @@ class RouteFragment : Fragment() {
8584

8685
viewModel.errorMessage.observe(viewLifecycleOwner) {
8786
it.getContentIfNotHandled()?.let { errorType ->
88-
val message = when (errorType) {
89-
ErrorType.NO_START -> getString(R.string.no_start_input)
90-
ErrorType.NO_END -> getString(R.string.no_end_input)
91-
}
87+
val message = getString(errorType.stringResourcesId)
9288

9389
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
9490
}

presentation/src/main/java/com/stop/ui/route/RouteViewModel.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ class RouteViewModel @Inject constructor(
6262
)
6363

6464
viewModelScope.launch {
65-
this@RouteViewModel._routeResponse.value = getRouteUseCase(routeRequest)
65+
val itineraries = getRouteUseCase(routeRequest)
66+
if (itineraries.isEmpty()) {
67+
_errorMessage.value = Event(ErrorType.NO_ROUTE_RESULT)
68+
return@launch
69+
}
70+
this@RouteViewModel._routeResponse.value = itineraries
6671
}
6772
}
6873

0 commit comments

Comments
 (0)