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
Expand Up @@ -27,6 +27,7 @@ import io.ktor.client.statement.HttpResponse
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.http.contentType
import timber.log.Timber

internal class AuthApiImpl(
private val client: HttpClient
Expand All @@ -51,9 +52,9 @@ internal class AuthApiImpl(
contentType(ContentType.Application.Json)
}.toSignInResult()
} catch(e: ResponseException){
handleSignInErrorResponse(e.response.status)
handleSignInError(e.response.status)
} catch(e: Exception){
handleSignInErrorResponse(HttpStatusCode(900, e.message ?: "Unknown Exception"))
handleSignInError(HttpStatusCode(900, e.message ?: "Unknown Exception"))
}
}

Expand Down Expand Up @@ -104,27 +105,25 @@ internal class AuthApiImpl(
}
}

private fun handleSignInErrorResponse(httpStatusCode: HttpStatusCode): SignInResult {
println("Error SignIn: ${httpStatusCode.description}")
return SignInResult.DefaultError
private fun handleSignInError(httpStatusCode: HttpStatusCode): SignInResult {
return when (httpStatusCode) {
HttpStatusCode.Unauthorized -> SignInResult.DefaultError
else -> SignInResult.DefaultError
}
}
private fun handleCreateAccountErrorResponse(httpStatusCode: HttpStatusCode): CreateAccountResult {
println("Error SignIn: ${httpStatusCode.description}")
return CreateAccountResult.Error(R.string.api_unexpected_error)
}

private fun handleForgotPasswordError(httpStatusCode: HttpStatusCode): ForgotPasswordResult {
println("Error: ${httpStatusCode.description}")
return ForgotPasswordResult.DefaultError
}

private fun handleValidateCodeError(httpStatusCode: HttpStatusCode): ValidateCodeResult {
println("Error: ${httpStatusCode.description}")
return ValidateCodeResult.DefaultError
}

private fun handleCreateNewPasswordError(httpStatusCode: HttpStatusCode): CreateNewPasswordResult {
println("Error: ${httpStatusCode.description}")
return CreateNewPasswordResult.DefaultError
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.routinely.routinely.data.auth.model

import kotlinx.serialization.Serializable

@Serializable
data class TaskRequest(
val name: String,
val date: String,
val hour: String,
val description: String,
val priority: String,
val tag: String,
val category: String
val date: String,
val category: String,
val finallyDate: String,
val weekDays: List<String>,
val type: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,26 @@ internal class TaskApiImpl(
) : TaskApi {
override suspend fun addTask(taskRequest: TaskRequest): ApiResponse {
return try {
client.post(HttpRoutes.TASK) {
val response = client.post(HttpRoutes.TASK) {
setBody(taskRequest)
contentType(ContentType.Application.Json)
}.taskToApiResponse()
} catch(e: RedirectResponseException){
// 3xx - responses
}
response.taskToApiResponse()
} catch (e: RedirectResponseException) {
handleErrorApiErrorResponse()
} catch(e: ClientRequestException){
// 4xx - responses
} catch (e: ClientRequestException) {
handleErrorApiErrorResponse()
} catch(e: ServerResponseException){
// 5xx - responses
} catch (e: ServerResponseException) {
handleErrorApiErrorResponse()
} catch(e: Exception){
} catch (e: Exception) {
handleErrorApiErrorResponse()
}
}

override suspend fun getMonthTasks(month: Int, year: Int): Flow<ApiResponseWithData<List<TaskItem>>> = flow {
override suspend fun getMonthTasks(
month: Int,
year: Int,
): Flow<ApiResponseWithData<List<TaskItem>>> = flow {
emit(ApiResponseWithData.Loading())
try {
emit(
Expand All @@ -61,7 +62,7 @@ internal class TaskApiImpl(
}
}.toTaskItemList()
)
} catch (e:Exception){
} catch (e: Exception) {
e.printStackTrace()
emit(ApiResponseWithData.Error())
}
Expand All @@ -74,7 +75,7 @@ internal class TaskApiImpl(
appendPathSegments(taskId.toString())
}
}.toTaskItem()
} catch (e:Exception){
} catch (e: Exception) {
e.printStackTrace()
null
}
Expand All @@ -87,16 +88,16 @@ internal class TaskApiImpl(
appendPathSegments(taskId.toString())
}
}.excludeToApiResponse()
} catch(e: RedirectResponseException){
// 3xx - responses
} catch (e: RedirectResponseException) {

handleErrorApiErrorResponse()
} catch(e: ClientRequestException){
// 4xx - responses
} catch (e: ClientRequestException) {

handleErrorApiErrorResponse()
} catch(e: ServerResponseException){
// 5xx - responses
} catch (e: ServerResponseException) {

handleErrorApiErrorResponse()
} catch(e: Exception){
} catch (e: Exception) {
handleErrorApiErrorResponse()
}
}
Expand All @@ -112,16 +113,16 @@ internal class TaskApiImpl(
}
val test = response.taskUpdateToApiResponse()
return test
} catch(e: RedirectResponseException){
// 3xx - responses
} catch (e: RedirectResponseException) {

handleErrorApiErrorResponse()
} catch(e: ClientRequestException){
// 4xx - responses
} catch (e: ClientRequestException) {

handleErrorApiErrorResponse()
} catch(e: ServerResponseException){
// 5xx - responses
} catch (e: ServerResponseException) {

handleErrorApiErrorResponse()
} catch(e: Exception){
} catch (e: Exception) {
handleErrorApiErrorResponse()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,59 @@
package com.routinely.routinely.data.task.extensions

import com.routinely.routinely.R
import com.routinely.routinely.data.auth.model.ApiResponse
import com.routinely.routinely.data.auth.model.ApiResponseWithData
import com.routinely.routinely.util.TaskCategory
import com.routinely.routinely.util.TaskItem
import com.routinely.routinely.util.TaskItemRemote
import com.routinely.routinely.util.TaskListResponse
import com.routinely.routinely.util.TaskPriorities
import com.routinely.routinely.util.TaskTag
import io.ktor.client.call.body
import io.ktor.client.statement.HttpResponse
import io.ktor.http.HttpStatusCode
import kotlinx.serialization.Serializable
import timber.log.Timber


suspend fun HttpResponse.taskToApiResponse() : ApiResponse {
return when(this.status) {
@Serializable
data class ErrorResponse(
val errors: List<ErrorDetail>,
)

@Serializable
data class ErrorDetail(
val property: String?,
val message: String?,
)

suspend fun HttpResponse.taskToApiResponse(): ApiResponse {
return when (this.status) {
HttpStatusCode.Created -> {
ApiResponse.Success
}

else -> {
val test = this.body<Error>()
println("Property ${test.errors?.property} -- ${test.errors?.message}")
ApiResponse.DefaultError
try {
val errorResponse = this.body<ErrorResponse>()
if (errorResponse.errors.isNotEmpty()) {
ApiResponse.Error(message = R.string.api_unexpected_error)
} else {
ApiResponse.DefaultError
}
} catch (e: Exception) {
println("Erro ao processar resposta: ${e.message}")
Copy link

Copilot AI Apr 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Replace the println statement with a proper logging mechanism (e.g. Timber) to ensure consistent and production-ready error logging.

Suggested change
println("Erro ao processar resposta: ${e.message}")
Timber.e(e, "Erro ao processar resposta")

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eu ia falar isso, mas ele falou antes kkkk. Tbm recomendo usar o Timber, talvez o Timber.d e continuar a msg + o erro como estava antes ou como ele recomendou, vc que sabe.

ApiResponse.DefaultError
}
}
}
}

suspend fun HttpResponse.taskUpdateToApiResponse() : ApiResponse {
return when(this.status) {
suspend fun HttpResponse.taskUpdateToApiResponse(): ApiResponse {
return when (this.status) {
HttpStatusCode.OK -> {
ApiResponse.Success
}

else -> {
val test = this.body<Error>()
println("Property ${test.errors?.property} -- ${test.errors?.message}")
Expand All @@ -39,51 +62,58 @@ suspend fun HttpResponse.taskUpdateToApiResponse() : ApiResponse {
}
}

suspend fun HttpResponse.toTaskItemList() : ApiResponseWithData<List<TaskItem>> {
return when(this.status) {
suspend fun HttpResponse.toTaskItemList(): ApiResponseWithData<List<TaskItem>> {
return when (this.status) {
HttpStatusCode.OK -> {
val remote = this.body<List<TaskItemRemote>?>() ?: return ApiResponseWithData.EmptyData()
if(remote.isEmpty()) return ApiResponseWithData.EmptyData()

return ApiResponseWithData.Success(
remote.map {
TaskItem(
id = it.id,
name = it.name,
date = it.date,
hour = it.hour,
description = it.description,
tag = mapApiStringToTag(it.tag),
priority = mapApiStringToPriority(it.priority),
category = mapApiStringToCategory(it.category)
)
}
)
try {
val response =
this.body<TaskListResponse?>() ?: return ApiResponseWithData.EmptyData()
if (response.tasks.isEmpty()) return ApiResponseWithData.EmptyData()

ApiResponseWithData.Success(
response.tasks.map {
TaskItem(
id = it.id,
name = it.name,
date = it.date,
type = it.type.lowercase(),
category = it.category,
description = it.description,
finallyDate = it.finallyDate,
weekDays = it.weekDays
)
}
)
} catch (e: Exception) {
ApiResponseWithData.DefaultError()
}
}

else -> {
ApiResponseWithData.DefaultError()
}
}
}

suspend fun HttpResponse.toTaskItem() : TaskItem? {
return when(this.status) {
suspend fun HttpResponse.toTaskItem(): TaskItem? {
return when (this.status) {
HttpStatusCode.OK -> {
val remote = this.body<TaskItemRemote?>()
if(remote == null) return remote
if (remote == null) return remote
remote.let {
TaskItem(
id = it.id,
name = it.name,
date = it.date,
hour = it.hour,
type = it.type,
category = it.category,
description = it.description,
tag = mapApiStringToTag(it.tag),
priority = mapApiStringToPriority(it.priority),
category = mapApiStringToCategory(it.category)
finallyDate = it.finallyDate,
weekDays = it.weekDays
)
}
}

else -> {
println(this.status)
null
Expand All @@ -93,54 +123,23 @@ suspend fun HttpResponse.toTaskItem() : TaskItem? {

@Serializable
data class Error(
val errors: Errors?
val errors: Errors?,
)

@Serializable
data class Errors(
val property: String,
val message: String
val message: String,
)

fun HttpResponse.excludeToApiResponse() : ApiResponse {
return when(this.status) {
fun HttpResponse.excludeToApiResponse(): ApiResponse {
return when (this.status) {
HttpStatusCode.OK -> {
ApiResponse.Success
}

else -> {
ApiResponse.DefaultError
}
}
}

fun mapApiStringToCategory(apiString: String): TaskCategory {
return when (apiString) {
"career" -> TaskCategory.Career
"personal" -> TaskCategory.Personal
"health" -> TaskCategory.Health
"finance" -> TaskCategory.Finances
"study" -> TaskCategory.Studies
else -> throw IllegalArgumentException("Unknown category: $apiString")
}
}

private fun mapApiStringToPriority(apiString: String): TaskPriorities {
return when (apiString) {
"urgent" -> TaskPriorities.Urgent
"high" -> TaskPriorities.High
"medium" -> TaskPriorities.Medium
"low" -> TaskPriorities.Low
else -> throw IllegalArgumentException("Unknown priority: $apiString")
}
}

private fun mapApiStringToTag(apiString: String): TaskTag {
return when (apiString) {
"application" -> TaskTag.Candidacy
"account" -> TaskTag.Bill
"exercise" -> TaskTag.Exercise
"beauty" -> TaskTag.Beauty
"literature" -> TaskTag.Literature
else -> throw IllegalArgumentException("Unknown tag: $apiString")
}
}
Loading