Skip to content

Commit

Permalink
Merge pull request #1330 from Netflix/unwrapCompletionExceptionInExce…
Browse files Browse the repository at this point in the history
…ptionHandler

When an exception was thrown from a dataloader, it would be wrapped i…
  • Loading branch information
rreta04 committed Nov 22, 2022
2 parents 19a4eb6 + b57c162 commit 97f6c4c
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
Expand Up @@ -24,6 +24,7 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.util.ClassUtils
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CompletionException

/**
* Default DataFetcherExceptionHandler used by the framework, can be replaced with a custom implementation.
Expand All @@ -41,7 +42,7 @@ class DefaultDataFetcherExceptionHandler : DataFetcherExceptionHandler {
}

private fun doHandleException(handlerParameters: DataFetcherExceptionHandlerParameters): DataFetcherExceptionHandlerResult {
val exception = handlerParameters.exception
val exception = unwrapCompletionException(handlerParameters.exception)
logger.error(
"Exception while executing data fetcher for ${handlerParameters.path}: ${exception.message}",
exception
Expand All @@ -62,6 +63,10 @@ class DefaultDataFetcherExceptionHandler : DataFetcherExceptionHandler {
.build()
}

private fun unwrapCompletionException(e: Throwable): Throwable {
return if (e is CompletionException && e.cause != null) e.cause!! else e
}

companion object {

private val logger: Logger = LoggerFactory.getLogger(DefaultDataFetcherExceptionHandler::class.java)
Expand Down
Expand Up @@ -26,6 +26,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.security.access.AccessDeniedException
import java.util.concurrent.CompletionException

internal class DefaultDataFetcherExceptionHandlerTest {

Expand Down Expand Up @@ -126,4 +127,22 @@ internal class DefaultDataFetcherExceptionHandlerTest {
// We return null here because we don't want graphql-java to write classification field
assertThat(result.errors[0].errorType).isNull()
}

@Test
fun `CompletionException returns wrapped error code`() {
val completionException = CompletionException(
"com.netflix.graphql.dgs.exceptions.DgsEntityNotFoundException: Requested entity not found",
DgsEntityNotFoundException()
)
every { dataFetcherExceptionHandlerParameters.exception }.returns(completionException)

val result = DefaultDataFetcherExceptionHandler().handleException(dataFetcherExceptionHandlerParameters).get()
assertThat(result.errors.size).isEqualTo(1)

val extensions = result.errors[0].extensions
assertThat(extensions["errorType"]).isEqualTo("NOT_FOUND")

// We return null here because we don't want graphql-java to write classification field
assertThat(result.errors[0].errorType).isNull()
}
}

0 comments on commit 97f6c4c

Please sign in to comment.