{"record":{"id":"50798372ee6f6ed3","repo":"quarkusio/quarkus","slug":"cannot-transform-exception-failure-to-a-status","errorCode":null,"errorMessage":"Cannot transform exception ${failure} to a status exception","messagePattern":"Cannot transform exception (.+?) to a status exception","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/grpc/runtime/src/main/java/io/quarkus/grpc/auth/AuthExceptionHandlerProvider.java","lineNumber":29,"sourceCode":" * Provider for AuthExceptionHandler.\n *\n * To use a custom AuthExceptionHandler, extend {@link AuthExceptionHandler} and implement\n * an {@link AuthExceptionHandlerProvider} with priority greater than the default one.\n */\npublic interface AuthExceptionHandlerProvider extends Prioritized {\n    int DEFAULT_PRIORITY = 0;\n\n    <ReqT, RespT> AuthExceptionHandler<ReqT, RespT> createHandler(Listener<ReqT> listener,\n            ServerCall<ReqT, RespT> serverCall, Metadata metadata);\n\n    /**\n     * @param failure security exception this provider can handle according to the {@link #handlesException(Throwable)}\n     * @return status exception\n     */\n    default StatusException transformToStatusException(Throwable failure) {\n        // because by default we don't handle any exception\n        // the original behavior (before introduction of this method) is kept because 'handlesException' return false\n        throw new IllegalStateException(\"Cannot transform exception \" + failure + \" to a status exception\");\n    }\n\n    /**\n     * @param failure any gRPC request failure\n     * @return whether this provider should create response status for given failure\n     */\n    default boolean handlesException(Throwable failure) {\n        return false;\n    }\n}\n","sourceCodeStart":11,"sourceCodeEnd":40,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/auth/AuthExceptionHandlerProvider.java#L11-L40","documentation":"AuthExceptionHandlerProvider is a default interface method: the default implementation transforms no exceptions (handlesException returns false), so calling transformToStatusException on a provider that did not override it throws this IllegalStateException. It is a programming error: you invoked a provider for an exception it declared it cannot map to a gRPC status.","triggerScenarios":"Calling transformToStatusException directly on a custom/default provider without overriding the method; a custom provider overrides handles() to return true for some exception but forgets to override transformToStatusException, so toStatusException falls through to the default throw.","commonSituations":"Implementing a custom auth exception handler for Quarkus gRPC security and overriding handles()/handlesException() but not transformToStatusException; calling the default method in tests against the bare interface.","solutions":["In your AuthExceptionHandlerProvider implementation, override transformToStatusException(Throwable) and return an appropriate StatusException (e.g. Status.UNAUTHENTICATED.withCause(failure).asException()).","Make sure handles()/handlesException() only returns true for exceptions your transformToStatusException can actually map.","Extend an existing provider (e.g. JwtAuthenticationMechanism-based providers) instead of implementing the interface from scratch if you only need small changes.","If you hit this in a test, instantiate a concrete provider rather than the interface default."],"exampleFix":"// before\nclass MyProvider implements AuthExceptionHandlerProvider {\n  public boolean handlesException(Throwable t) { return t instanceof MyAuthException; }\n  // transformToStatusException not overridden\n}\n// after\n@Override\npublic StatusException transformToStatusException(Throwable failure) {\n  return Status.UNAUTHENTICATED.withDescription(failure.getMessage()).withCause(failure).asException();\n}","handlingStrategy":"try-catch","validationCode":"// before relying on a provider, verify it can transform\nif (provider.getClass() == AuthExceptionHandlerProvider.class)\n    throw new IllegalStateException(\"Default provider cannot transform exceptions; override transformToStatusException\");","typeGuard":"boolean canTransform(AuthExceptionHandlerProvider p) {\n  try { p.getClass().getMethod(\"transformToStatusException\", Throwable.class);\n        return p.getClass() != AuthExceptionHandlerProvider.class; }\n  catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n    statusException = provider.transformToStatusException(failure);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Cannot transform exception\")) {\n        // provider didn't override the method; map the failure yourself or fix the provider\n        statusException = Status.UNAUTHENTICATED.withCause(failure).asException();\n    } else throw e;\n}","preventionTips":["Always override transformToStatusException when writing a custom provider","Keep handlesException() and transformToStatusException consistent (only claim exceptions you can map)","Prefer extending an existing concrete provider over implementing the interface bare","Test the provider's transform path in unit tests"],"tags":["grpc","quarkus","auth","unimplemented-method"],"backgroundTag":"unhandled-security-exception","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}