diff --git a/src/main/kotlin/fr/dcproject/application/http/HttpErrorBadRequest.kt b/src/main/kotlin/fr/dcproject/application/http/HttpErrorBadRequest.kt new file mode 100644 index 0000000..88b4ae5 --- /dev/null +++ b/src/main/kotlin/fr/dcproject/application/http/HttpErrorBadRequest.kt @@ -0,0 +1,35 @@ +package fr.dcproject.application.http + +import fr.dcproject.application.http.HttpErrorBadRequest.InvalidParam +import io.konform.validation.ValidationResult +import io.ktor.http.HttpStatusCode + +class BadRequestException(val httpError: HttpErrorBadRequest) : Exception() + +class HttpErrorBadRequest( + statusCode: HttpStatusCode, + val title: String = statusCode.description, + val invalidParams: List, +) { + val statusCode: Int = statusCode.value + data class InvalidParam( + val name: String, + val reason: String + ) +} + +fun ValidationResult<*>.toOutput() = HttpErrorBadRequest( + HttpStatusCode.BadRequest, + invalidParams = this.errors.map { + InvalidParam( + it.dataPath, + it.message + ) + } +) + +fun ValidationResult<*>.badRequestIfNotValid() { + if (errors.size > 0) { + throw BadRequestException(toOutput()) + } +} diff --git a/src/main/kotlin/fr/dcproject/application/http/HttpStatusError.kt b/src/main/kotlin/fr/dcproject/application/http/HttpStatusError.kt index 319c0ee..76aa5bf 100644 --- a/src/main/kotlin/fr/dcproject/application/http/HttpStatusError.kt +++ b/src/main/kotlin/fr/dcproject/application/http/HttpStatusError.kt @@ -4,14 +4,11 @@ import com.github.jasync.sql.db.postgresql.exceptions.GenericDatabaseException import fr.dcproject.common.security.AccessDeniedException import fr.dcproject.component.auth.ForbiddenException import fr.dcproject.component.auth.user -import io.konform.validation.ValidationResult -import io.ktor.application.ApplicationCall import io.ktor.application.call import io.ktor.features.NotFoundException import io.ktor.features.StatusPages import io.ktor.http.HttpStatusCode import io.ktor.response.respond -import io.ktor.util.pipeline.PipelineContext import java.util.concurrent.CompletionException class HttpError( @@ -20,8 +17,6 @@ class HttpError( val type: String? = null, val title: String = cause?.message ?: statusCode.description, val detail: String? = null, - val invalidParams: List? = null, - val stackTrace: String? = cause?.stackTraceToString() ) { val statusCode: Int = statusCode.value data class InvalidParam( @@ -30,30 +25,6 @@ class HttpError( ) } -fun ValidationResult<*>.toOutput(): HttpError { - return HttpError( - HttpStatusCode.BadRequest, - invalidParams = this.errors.map { - HttpError.InvalidParam( - it.dataPath, - it.message - ) - } - ) -} - -suspend fun PipelineContext<*, ApplicationCall>.respondIfNotValid(validationResult: ValidationResult<*>): HttpError? { - if (validationResult.errors.size > 0) { - val out = validationResult.toOutput() - this.call.respond( - HttpStatusCode.BadRequest, - out - ) - return out - } - return null -} - fun statusPagesInstallation(): StatusPages.Configuration.() -> Unit = { exception { e -> val parent = e.cause?.cause @@ -106,4 +77,7 @@ fun statusPagesInstallation(): StatusPages.Configuration.() -> Unit = { call.respond(HttpStatusCode.Forbidden, it) } } + exception { e -> + call.respond(HttpStatusCode.BadRequest, e.httpError) + } } diff --git a/src/main/kotlin/fr/dcproject/component/article/routes/FindArticles.kt b/src/main/kotlin/fr/dcproject/component/article/routes/FindArticles.kt index c1df6d6..2d8bd9a 100644 --- a/src/main/kotlin/fr/dcproject/component/article/routes/FindArticles.kt +++ b/src/main/kotlin/fr/dcproject/component/article/routes/FindArticles.kt @@ -1,6 +1,6 @@ package fr.dcproject.component.article.routes -import fr.dcproject.application.http.respondIfNotValid +import fr.dcproject.application.http.badRequestIfNotValid import fr.dcproject.common.response.toOutput import fr.dcproject.common.security.assert import fr.dcproject.common.validation.isUuid @@ -74,7 +74,7 @@ object FindArticles { fun Route.findArticles(repo: ArticleRepository, ac: ArticleAccessControl) { get { - respondIfNotValid(it.validate())?.apply { return@get } + it.validate().badRequestIfNotValid() repo.findArticles(it) .apply { ac.assert { canView(result, citizenOrNull) } } diff --git a/src/main/resources/openapi.yaml b/src/main/resources/openapi.yaml index e453251..7ce9bab 100644 --- a/src/main/resources/openapi.yaml +++ b/src/main/resources/openapi.yaml @@ -134,6 +134,12 @@ paths: tags: - article operationId: getArticle + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/direction' + - $ref: '#/components/parameters/search' responses: 200: description: The Article objects @@ -149,6 +155,12 @@ paths: tags: - article operationId: getArticleVersions + parameters: + - $ref: '#/components/parameters/page' + - $ref: '#/components/parameters/limit' + - $ref: '#/components/parameters/sort' + - $ref: '#/components/parameters/direction' + - $ref: '#/components/parameters/search' responses: 200: description: The versions of Article @@ -2224,20 +2236,8 @@ components: properties: statusCode: type: integer - type: - type: string - nullable: true title: type: string - detail: - type: string - nullable: true - cause: - type: string - nullable: true - stackTrace: - type: string - nullable: true invalidParams: type: array items: