Feature/graphql log execution exceptions (#1319)

* Log exceptions during graphql execution

Exceptions got swallowed by graphql

* Add stack trace to error in graphql response

Depending on the exceptions error message, the error in the response might be quite useless (e.g. "Stub!" error in android classes)
This commit is contained in:
schroda
2025-03-23 00:35:16 +01:00
committed by GitHub
parent c3347d94ab
commit 4c5598cedf

View File

@@ -11,8 +11,12 @@ import com.expediagroup.graphql.generator.execution.FlowSubscriptionExecutionStr
import com.expediagroup.graphql.server.execution.GraphQLRequestHandler import com.expediagroup.graphql.server.execution.GraphQLRequestHandler
import com.expediagroup.graphql.server.execution.GraphQLServer import com.expediagroup.graphql.server.execution.GraphQLServer
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import graphql.ExceptionWhileDataFetching
import graphql.GraphQL import graphql.GraphQL
import graphql.execution.AsyncExecutionStrategy import graphql.execution.AsyncExecutionStrategy
import graphql.execution.DataFetcherExceptionHandler
import graphql.execution.DataFetcherExceptionHandlerResult
import io.github.oshai.kotlinlogging.KotlinLogging
import io.javalin.http.Context import io.javalin.http.Context
import io.javalin.websocket.WsCloseContext import io.javalin.websocket.WsCloseContext
import io.javalin.websocket.WsMessageContext import io.javalin.websocket.WsMessageContext
@@ -21,6 +25,7 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import suwayomi.tachidesk.graphql.server.subscriptions.ApolloSubscriptionProtocolHandler import suwayomi.tachidesk.graphql.server.subscriptions.ApolloSubscriptionProtocolHandler
import suwayomi.tachidesk.server.JavalinSetup.future
class TachideskGraphQLServer( class TachideskGraphQLServer(
requestParser: JavalinGraphQLRequestParser, requestParser: JavalinGraphQLRequestParser,
@@ -44,11 +49,34 @@ class TachideskGraphQLServer(
} }
companion object { companion object {
private val logger = KotlinLogging.logger {}
private val exceptionHandler =
DataFetcherExceptionHandler { handlerParameters ->
future {
val exception = handlerParameters.exception
val sourceLocation = handlerParameters.sourceLocation
val path = handlerParameters.path
logger.error(exception) { "GraphQL execution failed due to" }
val error =
ExceptionWhileDataFetching(
path,
Throwable(exception.message + "\r\n\r\n" + exception.stackTraceToString(), exception),
sourceLocation,
)
DataFetcherExceptionHandlerResult.newResult().error(error).build()
}
}
private fun getGraphQLObject(): GraphQL = private fun getGraphQLObject(): GraphQL =
GraphQL GraphQL
.newGraphQL(schema) .newGraphQL(schema)
.subscriptionExecutionStrategy(FlowSubscriptionExecutionStrategy()) .queryExecutionStrategy(AsyncExecutionStrategy(exceptionHandler))
.mutationExecutionStrategy(AsyncExecutionStrategy()) .mutationExecutionStrategy(AsyncExecutionStrategy(exceptionHandler))
.subscriptionExecutionStrategy(FlowSubscriptionExecutionStrategy(exceptionHandler))
.build() .build()
fun create(): TachideskGraphQLServer { fun create(): TachideskGraphQLServer {