{"record":{"id":"ae31207f33134e59","repo":"apache/dolphinscheduler","slug":"grpc-handle-exception","errorCode":null,"errorMessage":"gRPC handle exception:","messagePattern":"gRPC handle exception:","errorType":"exception","errorClass":"GrpcTaskException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-task-plugin/dolphinscheduler-task-grpc/src/main/java/org/apache/dolphinscheduler/plugin/task/grpc/GrpcTask.java","lineNumber":93,"sourceCode":"            ManagedChannel channel;\n            if (grpcParameters.getChannelCredentialType() == GrpcCredentialType.TLS_DEFAULT) {\n                TlsChannelCredentials creds = (TlsChannelCredentials) TlsChannelCredentials.create();\n                channel = GrpcDynamicService.ChannelFactory.createChannel(grpcParameters.getUrl(), creds);\n            } else {\n                channel = GrpcDynamicService.ChannelFactory.createChannel(grpcParameters.getUrl());\n            }\n            Descriptors.FileDescriptor fileDesc =\n                    JSONDescriptorHelper.fileDescFromJSON(grpcParameters.getGrpcServiceDefinitionJSON());\n            GrpcDynamicService stubService = new GrpcDynamicService(channel, fileDesc);\n            DynamicMessage message = stubService.call(grpcParameters.getMethodName(), grpcParameters.getMessage(),\n                    grpcParameters.getConnectTimeoutMs());\n            Printer printer = JsonFormat.printer().omittingInsignificantWhitespace();\n            addDefaultOutput(printer.print(message));\n        } catch (StatusRuntimeException statusre) {\n            validateResponse(statusre.getStatus());\n            return;\n        } catch (Exception e) {\n            throw new GrpcTaskException(\"gRPC handle exception:\", e);\n        }\n        validateResponse(Status.OK);\n    }\n\n    @Override\n    public void cancel() throws TaskException {\n        // Do nothing when task to be canceled\n    }\n\n    private void validateResponse(Status statusCode) {\n        switch (grpcParameters.getGrpcCheckCondition()) {\n            case STATUS_CODE_DEFAULT:\n                if (!statusCode.isOk()) {\n                    log.error(\n                            \"grpc request failed, url: {}, method: {}, statusCode: {} (expected OK), checkCondition: {}\",\n                            grpcParameters.getUrl(), grpcParameters.getMethodName(), statusCode.getCode(),\n                            GrpcCheckCondition.STATUS_CODE_DEFAULT.name());\n                    exitStatusCode = TaskConstants.EXIT_CODE_FAILURE;","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-task-plugin/dolphinscheduler-task-grpc/src/main/java/org/apache/dolphinscheduler/plugin/task/grpc/GrpcTask.java#L75-L111","documentation":"GrpcTask.handle() builds a channel/stub and invokes the configured gRPC method. Any unexpected exception during the call (channel creation, message construction, serialization, or non-status runtime errors not caught as StatusRuntimeException) is wrapped as GrpcTaskException('gRPC handle exception:'). StatusRuntimeException is handled separately via validateResponse, so this indicates an error outside the normal gRPC status path.","triggerScenarios":"Exception while parsing request JSON into the protobuf message, building the channel (bad target/host), JsonFormat.printer failures on the response, or any non-StatusRuntimeException from the stub call.","commonSituations":"Invalid request parameter values that fail protobuf JSON parsing; malformed grpc target URL; TLS/network misconfig throwing IO exceptions inside the stub; proto message field type mismatches in request body.","solutions":["Check the wrapped cause 'e' in the worker logs for the real failure (parse error vs network error)","Validate the request body JSON against the proto message field names/types","Verify the gRPC target address and TLS settings are reachable from the worker","Fix parameter values in the task form and re-run"],"exampleFix":"// before\nthrow new GrpcTaskException(\"gRPC handle exception:\", e);\n// after\nthrow new GrpcTaskException(\"gRPC handle exception for url=\" + grpcParameters.getUrl() + \", method=\" + grpcParameters.getMethodName(), e);","handlingStrategy":"try-catch","validationCode":"// validate request JSON against proto before calling\nMessage.Builder b = descriptor.findMessageTypeByName(requestMessageType).toProto().toBuilder();\nJsonFormat.parser().ignoringUnknownFields().merge(requestJson, b); // throws if field types mismatch","typeGuard":null,"tryCatchPattern":"try {\n    task.handle(null);\n} catch (GrpcTaskException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof StatusRuntimeException) { /* handled by validateResponse path */ }\n    else if (cause instanceof InvalidProtocolBufferException) { /* fix request body */ }\n    else { /* network/channel issue: check target and TLS */ }\n}","preventionTips":["Validate request JSON field names/types against the proto message","Test connectivity from the worker host to the gRPC target","Handle StatusRuntimeException separately from generic Exception","Keep channel/stub construction failures logged with full cause"],"tags":["grpc","network","protobuf","unhandled-exception"],"backgroundTag":"grpc-call-failed","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}