Error codes #84
@@ -11,23 +11,72 @@ import io.ktor.http.HttpStatusCode
|
|||||||
import io.ktor.response.respond
|
import io.ktor.response.respond
|
||||||
import java.util.concurrent.CompletionException
|
import java.util.concurrent.CompletionException
|
||||||
|
|
||||||
|
class HttpError(
|
||||||
|
statusCode: HttpStatusCode,
|
||||||
|
val cause: Throwable? = null,
|
||||||
|
val type: String? = null,
|
||||||
|
val title: String = cause?.message ?: statusCode.description,
|
||||||
|
val detail: String? = null,
|
||||||
|
val invalidParams: List<InvalidParam>? = null,
|
||||||
|
val stackTrace: String? = cause?.stackTraceToString()
|
||||||
|
) {
|
||||||
|
val statusCode: Int = statusCode.value
|
||||||
|
data class InvalidParam(
|
||||||
|
val name: String,
|
||||||
|
val reason: String
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun statusPagesInstallation(): StatusPages.Configuration.() -> Unit = {
|
fun statusPagesInstallation(): StatusPages.Configuration.() -> Unit = {
|
||||||
exception<CompletionException> { e ->
|
exception<CompletionException> { e ->
|
||||||
val parent = e.cause?.cause
|
val parent = e.cause?.cause
|
||||||
if (parent is GenericDatabaseException) {
|
if (parent is GenericDatabaseException) {
|
||||||
call.respond(HttpStatusCode.BadRequest, parent.errorMessage.message!!)
|
HttpError(
|
||||||
|
HttpStatusCode.BadRequest,
|
||||||
|
cause = parent
|
||||||
|
).let {
|
||||||
|
call.respond(HttpStatusCode.BadRequest, it)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw e
|
HttpError(
|
||||||
|
HttpStatusCode.BadRequest,
|
||||||
|
cause = e
|
||||||
|
).let {
|
||||||
|
call.respond(HttpStatusCode.InternalServerError, it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exception<NotFoundException> { e ->
|
exception<NotFoundException> { e ->
|
||||||
call.respond(HttpStatusCode.NotFound, e.message!!)
|
HttpError(
|
||||||
}
|
HttpStatusCode.NotFound,
|
||||||
exception<AccessDeniedException> {
|
cause = e
|
||||||
if (call.user == null) call.respond(HttpStatusCode.Unauthorized)
|
).let {
|
||||||
else call.respond(HttpStatusCode.Forbidden)
|
call.respond(HttpStatusCode.NotFound, it)
|
||||||
}
|
}
|
||||||
exception<ForbiddenException> {
|
}
|
||||||
call.respond(HttpStatusCode.Forbidden)
|
exception<AccessDeniedException> { e ->
|
||||||
|
if (call.user == null) {
|
||||||
|
HttpError(
|
||||||
|
HttpStatusCode.Unauthorized,
|
||||||
|
cause = e
|
||||||
|
).let {
|
||||||
|
call.respond(HttpStatusCode.Unauthorized, it)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HttpError(
|
||||||
|
HttpStatusCode.Forbidden,
|
||||||
|
cause = e
|
||||||
|
).let {
|
||||||
|
call.respond(HttpStatusCode.Forbidden, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exception<ForbiddenException> { e ->
|
||||||
|
HttpError(
|
||||||
|
HttpStatusCode.Forbidden,
|
||||||
|
cause = e
|
||||||
|
).let {
|
||||||
|
call.respond(HttpStatusCode.Forbidden, it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,18 @@ paths:
|
|||||||
type: integer
|
type: integer
|
||||||
401:
|
401:
|
||||||
$ref: '#/components/responses/401'
|
$ref: '#/components/responses/401'
|
||||||
|
403:
|
||||||
|
description: Forbiden
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
description: Forbiden
|
||||||
|
properties:
|
||||||
|
statusCode:
|
||||||
|
type: integer
|
||||||
|
title:
|
||||||
|
type: string
|
||||||
|
|
||||||
/articles/{article}:
|
/articles/{article}:
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/article'
|
- $ref: '#/components/parameters/article'
|
||||||
|
|||||||
@@ -12,11 +12,13 @@ import integration.steps.given.`authenticated as`
|
|||||||
import integration.steps.then.`And have property`
|
import integration.steps.then.`And have property`
|
||||||
import integration.steps.then.`And the response should contain list`
|
import integration.steps.then.`And the response should contain list`
|
||||||
import integration.steps.then.`And the response should contain pattern`
|
import integration.steps.then.`And the response should contain pattern`
|
||||||
|
import integration.steps.then.`And the response should contain`
|
||||||
import integration.steps.then.`And the response should not be null`
|
import integration.steps.then.`And the response should not be null`
|
||||||
import integration.steps.then.`And the response should not contain`
|
import integration.steps.then.`And the response should not contain`
|
||||||
import integration.steps.then.`Then the response should be`
|
import integration.steps.then.`Then the response should be`
|
||||||
import integration.steps.then.`whish contains`
|
import integration.steps.then.`whish contains`
|
||||||
import integration.steps.then.and
|
import integration.steps.then.and
|
||||||
|
import io.ktor.http.HttpStatusCode.Companion.Forbidden
|
||||||
import io.ktor.http.HttpStatusCode.Companion.OK
|
import io.ktor.http.HttpStatusCode.Companion.OK
|
||||||
import org.junit.jupiter.api.Tag
|
import org.junit.jupiter.api.Tag
|
||||||
import org.junit.jupiter.api.Tags
|
import org.junit.jupiter.api.Tags
|
||||||
@@ -104,4 +106,30 @@ class `Article routes` : BaseTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `I cannot create an article if I'm not connected`() {
|
||||||
|
withIntegrationApplication {
|
||||||
|
`When I send a POST request`("/articles") {
|
||||||
|
`with body`(
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"versionId": "e3c7ce42-241c-4caf-9a59-aba4e466440e",
|
||||||
|
"title": "title2",
|
||||||
|
"anonymous": false,
|
||||||
|
"content": "content2",
|
||||||
|
"description": "description2",
|
||||||
|
"tags": [
|
||||||
|
"green"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
} `Then the response should be` Forbidden and {
|
||||||
|
`And the response should not be null`()
|
||||||
|
`And the response should contain`("$.statusCode", 403)
|
||||||
|
`And the response should contain`("$.title", "No User Connected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user