Skip to content

Commit 6b0b639

Browse files
authored
Merge pull request #19 from nativeapptemplate/extract_api_error_handling
Extract duplicated API error handling into shared extensions
2 parents d76d6d3 + a71c911 commit 6b0b639

7 files changed

Lines changed: 160 additions & 522 deletions

File tree

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/data/item_tag/ItemTagRepositoryImpl.kt

Lines changed: 8 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import com.nativeapptemplate.nativeapptemplatefree.datastore.NatPreferencesDataS
44
import com.nativeapptemplate.nativeapptemplatefree.model.*
55
import com.nativeapptemplate.nativeapptemplatefree.network.Dispatcher
66
import com.nativeapptemplate.nativeapptemplatefree.network.NatDispatchers
7-
import com.skydoves.sandwich.message
8-
import com.skydoves.sandwich.retrofit.serialization.deserializeErrorBody
9-
import com.skydoves.sandwich.suspendOnFailure
10-
import com.skydoves.sandwich.suspendOnSuccess
7+
import com.nativeapptemplate.nativeapptemplatefree.network.emitApiResponse
118
import kotlinx.coroutines.CoroutineDispatcher
129
import kotlinx.coroutines.flow.first
1310
import kotlinx.coroutines.flow.flow
@@ -27,27 +24,7 @@ class ItemTagRepositoryImpl @Inject constructor(
2724
mtcPreferencesDataSource.userData.first().accountId,
2825
shopId,
2926
)
30-
31-
response.suspendOnSuccess {
32-
emit(data)
33-
}.suspendOnFailure {
34-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
35-
36-
try {
37-
nativeAppTemplateApiError = response.deserializeErrorBody<ItemTags, NativeAppTemplateApiError>()
38-
} catch (exception: Exception) {
39-
val message = "Not processable error(${message()})."
40-
throw Exception(message)
41-
}
42-
43-
if (nativeAppTemplateApiError != null) {
44-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
45-
throw Exception(message)
46-
} else {
47-
val message = "Not processable error(${message()})."
48-
throw Exception(message)
49-
}
50-
}
27+
emitApiResponse(response)
5128
}.flowOn(ioDispatcher)
5229

5330
override fun getItemTag(
@@ -57,177 +34,51 @@ class ItemTagRepositoryImpl @Inject constructor(
5734
mtcPreferencesDataSource.userData.first().accountId,
5835
id,
5936
)
60-
61-
response.suspendOnSuccess {
62-
emit(data)
63-
}.suspendOnFailure {
64-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
65-
66-
try {
67-
nativeAppTemplateApiError = response.deserializeErrorBody<ItemTag, NativeAppTemplateApiError>()
68-
} catch (exception: Exception) {
69-
val message = "Not processable error(${message()})."
70-
throw Exception(message)
71-
}
72-
73-
if (nativeAppTemplateApiError != null) {
74-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
75-
throw Exception(message)
76-
} else {
77-
val message = "Not processable error(${message()})."
78-
throw Exception(message)
79-
}
80-
}
37+
emitApiResponse(response)
8138
}.flowOn(ioDispatcher)
8239

8340
override fun createItemTag(
8441
shopId: String,
8542
itemTagBody: ItemTagBody,
8643
) = flow {
87-
var itemTag: ItemTag
88-
8944
val response = api.createItemTag(
9045
mtcPreferencesDataSource.userData.first().accountId,
9146
shopId,
9247
itemTagBody,
9348
)
94-
95-
response.suspendOnSuccess {
96-
itemTag = data
97-
emit(itemTag)
98-
}.suspendOnFailure {
99-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
100-
101-
try {
102-
nativeAppTemplateApiError = response.deserializeErrorBody<ItemTag, NativeAppTemplateApiError>()
103-
} catch (exception: Exception) {
104-
val message = "Not processable error(${message()})."
105-
throw Exception(message)
106-
}
107-
108-
if (nativeAppTemplateApiError != null) {
109-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
110-
throw Exception(message)
111-
} else {
112-
val message = "Not processable error(${message()})."
113-
throw Exception(message)
114-
}
115-
}
49+
emitApiResponse(response)
11650
}.flowOn(ioDispatcher)
11751

11852
override fun updateItemTag(
11953
id: String,
12054
itemTagBody: ItemTagBody,
12155
) = flow {
122-
var itemTag: ItemTag
123-
12456
val response = api.updateItemTag(
12557
mtcPreferencesDataSource.userData.first().accountId,
12658
id,
12759
itemTagBody,
12860
)
129-
130-
response.suspendOnSuccess {
131-
itemTag = data
132-
emit(itemTag)
133-
}.suspendOnFailure {
134-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
135-
136-
try {
137-
nativeAppTemplateApiError = response.deserializeErrorBody<ItemTag, NativeAppTemplateApiError>()
138-
} catch (exception: Exception) {
139-
val message = "Not processable error(${message()})."
140-
throw Exception(message)
141-
}
142-
143-
if (nativeAppTemplateApiError != null) {
144-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
145-
throw Exception(message)
146-
} else {
147-
val message = "Not processable error(${message()})."
148-
throw Exception(message)
149-
}
150-
}
61+
emitApiResponse(response)
15162
}.flowOn(ioDispatcher)
15263

15364
override fun deleteItemTag(
15465
id: String,
15566
) = flow {
15667
val response = api.deleteItemTag(mtcPreferencesDataSource.userData.first().accountId, id)
157-
158-
response.suspendOnSuccess {
159-
emit(true)
160-
}.suspendOnFailure {
161-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
162-
163-
try {
164-
nativeAppTemplateApiError = response.deserializeErrorBody<Status, NativeAppTemplateApiError>()
165-
} catch (exception: Exception) {
166-
val message = "Not processable error(${message()})."
167-
throw Exception(message)
168-
}
169-
170-
if (nativeAppTemplateApiError != null) {
171-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
172-
throw Exception(message)
173-
} else {
174-
val message = "Not processable error(${message()})."
175-
throw Exception(message)
176-
}
177-
}
68+
emitApiResponse<Status, Boolean>(response) { true }
17869
}.flowOn(ioDispatcher)
17970

18071
override fun completeItemTag(
18172
id: String,
18273
) = flow {
18374
val response = api.completeItemTag(mtcPreferencesDataSource.userData.first().accountId, id)
184-
185-
response.suspendOnSuccess {
186-
emit(data)
187-
}.suspendOnFailure {
188-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
189-
190-
try {
191-
nativeAppTemplateApiError = response.deserializeErrorBody<ItemTag, NativeAppTemplateApiError>()
192-
} catch (exception: Exception) {
193-
val message = "Not processable error(${message()})."
194-
throw Exception(message)
195-
}
196-
197-
if (nativeAppTemplateApiError != null) {
198-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
199-
throw Exception(message)
200-
} else {
201-
val message = "Not processable error(${message()})."
202-
throw Exception(message)
203-
}
204-
}
75+
emitApiResponse(response)
20576
}.flowOn(ioDispatcher)
20677

20778
override fun resetItemTag(
20879
id: String,
20980
) = flow {
21081
val response = api.resetItemTag(mtcPreferencesDataSource.userData.first().accountId, id)
211-
212-
response.suspendOnSuccess {
213-
emit(data)
214-
}.suspendOnFailure {
215-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
216-
217-
try {
218-
nativeAppTemplateApiError = response.deserializeErrorBody<ItemTag, NativeAppTemplateApiError>()
219-
} catch (exception: Exception) {
220-
val message = "Not processable error(${message()})."
221-
throw Exception(message)
222-
}
223-
224-
if (nativeAppTemplateApiError != null) {
225-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
226-
throw Exception(message)
227-
} else {
228-
val message = "Not processable error(${message()})."
229-
throw Exception(message)
230-
}
231-
}
82+
emitApiResponse(response)
23283
}.flowOn(ioDispatcher)
23384
}

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/data/login/AccountPasswordRepositoryImpl.kt

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import com.nativeapptemplate.nativeapptemplatefree.datastore.NatPreferencesDataS
44
import com.nativeapptemplate.nativeapptemplatefree.model.*
55
import com.nativeapptemplate.nativeapptemplatefree.network.Dispatcher
66
import com.nativeapptemplate.nativeapptemplatefree.network.NatDispatchers
7-
import com.skydoves.sandwich.message
8-
import com.skydoves.sandwich.retrofit.serialization.deserializeErrorBody
9-
import com.skydoves.sandwich.suspendOnFailure
10-
import com.skydoves.sandwich.suspendOnSuccess
7+
import com.nativeapptemplate.nativeapptemplatefree.network.emitApiResponse
118
import kotlinx.coroutines.CoroutineDispatcher
129
import kotlinx.coroutines.flow.first
1310
import kotlinx.coroutines.flow.flow
@@ -26,26 +23,6 @@ class AccountPasswordRepositoryImpl @Inject constructor(
2623
natPreferencesDataSource.userData.first().accountId,
2724
updatePasswordBody,
2825
)
29-
30-
response.suspendOnSuccess {
31-
emit(true)
32-
}.suspendOnFailure {
33-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
34-
35-
try {
36-
nativeAppTemplateApiError = response.deserializeErrorBody<Status, NativeAppTemplateApiError>()
37-
} catch (exception: Exception) {
38-
val message = "Not processable error(${message()})."
39-
throw Exception(message)
40-
}
41-
42-
if (nativeAppTemplateApiError != null) {
43-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
44-
throw Exception(message)
45-
} else {
46-
val message = "Not processable error(${message()})."
47-
throw Exception(message)
48-
}
49-
}
26+
emitApiResponse<Status, Boolean>(response) { true }
5027
}.flowOn(ioDispatcher)
5128
}

app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/data/login/LoginRepositoryImpl.kt

Lines changed: 5 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import com.nativeapptemplate.nativeapptemplatefree.model.LoggedInShopkeeper
77
import com.nativeapptemplate.nativeapptemplatefree.model.Login
88
import com.nativeapptemplate.nativeapptemplatefree.network.Dispatcher
99
import com.nativeapptemplate.nativeapptemplatefree.network.NatDispatchers
10+
import com.nativeapptemplate.nativeapptemplatefree.network.emitApiResponse
1011
import com.skydoves.sandwich.message
11-
import com.skydoves.sandwich.retrofit.serialization.deserializeErrorBody
1212
import com.skydoves.sandwich.suspendOnFailure
1313
import com.skydoves.sandwich.suspendOnSuccess
1414
import kotlinx.coroutines.CoroutineDispatcher
@@ -31,31 +31,8 @@ class LoginRepositoryImpl @Inject constructor(
3131
override fun login(
3232
login: Login,
3333
) = flow {
34-
var loggedInShopkeeper: LoggedInShopkeeper
35-
3634
val response = api.login(login)
37-
38-
response.suspendOnSuccess {
39-
loggedInShopkeeper = data
40-
emit(loggedInShopkeeper)
41-
}.suspendOnFailure {
42-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
43-
44-
try {
45-
nativeAppTemplateApiError = response.deserializeErrorBody<LoggedInShopkeeper, NativeAppTemplateApiError>()
46-
} catch (exception: Exception) {
47-
val message = "Not processable error(${message()})."
48-
throw Exception(message)
49-
}
50-
51-
if (nativeAppTemplateApiError != null) {
52-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
53-
throw Exception(message)
54-
} else {
55-
val message = "Not processable error(${message()})."
56-
throw Exception(message)
57-
}
58-
}
35+
emitApiResponse(response)
5936
}.flowOn(ioDispatcher)
6037

6138
override val userData: Flow<UserData> =
@@ -77,81 +54,21 @@ class LoginRepositoryImpl @Inject constructor(
7754
val response = api.getPermissions(
7855
userData.first().accountId,
7956
)
80-
81-
response.suspendOnSuccess {
82-
emit(data)
83-
}.suspendOnFailure {
84-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
85-
86-
try {
87-
nativeAppTemplateApiError = response.deserializeErrorBody<Permissions, NativeAppTemplateApiError>()
88-
} catch (exception: Exception) {
89-
val message = "Not processable error(${message()})."
90-
throw Exception(message)
91-
}
92-
93-
if (nativeAppTemplateApiError != null) {
94-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
95-
throw Exception(message)
96-
} else {
97-
val message = "Not processable error(${message()})."
98-
throw Exception(message)
99-
}
100-
}
57+
emitApiResponse(response)
10158
}.flowOn(ioDispatcher)
10259

10360
override fun updateConfirmedPrivacyVersion() = flow {
10461
val response = api.updateConfirmedPrivacyVersion(
10562
natPreferencesDataSource.userData.first().accountId,
10663
)
107-
108-
response.suspendOnSuccess {
109-
emit(true)
110-
}.suspendOnFailure { // handles the all error cases from the API request fails.
111-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
112-
113-
try {
114-
nativeAppTemplateApiError = response.deserializeErrorBody<Status, NativeAppTemplateApiError>()
115-
} catch (exception: Exception) {
116-
val message = "Not processable error(${message()})."
117-
throw Exception(message)
118-
}
119-
120-
if (nativeAppTemplateApiError != null) {
121-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
122-
throw Exception(message)
123-
} else {
124-
val message = "Not processable error(${message()})."
125-
throw Exception(message)
126-
}
127-
}
64+
emitApiResponse<Status, Boolean>(response) { true }
12865
}.flowOn(ioDispatcher)
12966

13067
override fun updateConfirmedTermsVersion() = flow {
13168
val response = api.updateConfirmedTermsVersion(
13269
natPreferencesDataSource.userData.first().accountId,
13370
)
134-
135-
response.suspendOnSuccess {
136-
emit(true)
137-
}.suspendOnFailure { // handles the all error cases from the API request fails.
138-
val nativeAppTemplateApiError: NativeAppTemplateApiError?
139-
140-
try {
141-
nativeAppTemplateApiError = response.deserializeErrorBody<Status, NativeAppTemplateApiError>()
142-
} catch (exception: Exception) {
143-
val message = "Not processable error(${message()})."
144-
throw Exception(message)
145-
}
146-
147-
if (nativeAppTemplateApiError != null) {
148-
val message = "${nativeAppTemplateApiError.message} [Status: ${nativeAppTemplateApiError.code}]"
149-
throw Exception(message)
150-
} else {
151-
val message = "Not processable error(${message()})."
152-
throw Exception(message)
153-
}
154-
}
71+
emitApiResponse<Status, Boolean>(response) { true }
15572
}.flowOn(ioDispatcher)
15673

15774
override suspend fun setShouldFetchItemTagForShowTagInfoScan(shouldFetchItemTagForShowTagInfoScan: Boolean) {

0 commit comments

Comments
 (0)