Temporal跨语言调用报错WORKFLOW_TASK_FAILED的排查与解决
已解决结论
经排查,需要在客户端(TypeScript侧)创建并运行Worker,将工作流DummyActivity注册到Temporal。
问题:Temporal工作流报错
WORKFLOW_TASK_FAILED_CAUSE_WORKFLOW_WORKER_UNHANDLED_FAILURE 刚接触Temporal,完成官网转账教程后,搭建了两个服务的用例:
- 基于Golang的服务:实现独立活动并注册到Temporal;
- 基于TypeScript的客户端:定义工作流指定任务执行逻辑。
已部署Temporal服务器,两个服务指向同一任务队列。客户端未实现活动,但拥有活动定义。运行客户端后,Temporal UI中工作流状态报错:WORKFLOW_TASK_FAILED_CAUSE_WORKFLOW_WORKER_UNHANDLED_FAILURE。
期望客户端触发工作流,由Go服务顺利执行活动,且已验证Worker已注册到Temporal、任务队列配置正确。
相关代码
Golang服务端
main.go
package main import ( "log" "go.temporal.io/sdk/client" "go.temporal.io/sdk/worker" ) func main() { // Create Temporal client c, err := client.Dial(client.Options{ HostPort: "localhost:7233", Namespace: "default", }) if err != nil { log.Fatalln("Unable to create Temporal client", err) } defer c.Close() // Create a Temporal worker w := worker.New(c, "operation-queue", worker.Options{}) // Register activities w.RegisterActivity(DummyActivity1) w.RegisterActivity(DummyActivity2) // Start worker err = w.Run(worker.InterruptCh()) if err != nil { log.Fatalln("Unable to start Worker", err) } }
activities.go
package main import ( "context" "log" ) func DummyActivity1(ctx context.Context, input string) (string, error) { log.Println("Executing DummyActivity1 with input:", input) return input + " output1", nil } func DummyActivity2(ctx context.Context, input string) (string, error) { log.Println("Executing DummyActivity2 with input:", input) return input + " output2", nil }
TypeScript客户端(client.ts)
import { Connection, WorkflowClient } from '@temporalio/client'; import { proxyActivities } from '@temporalio/workflow'; import { ApplicationFailure } from '@temporalio/common'; export interface Activities { DummyActivity1: (input: string) => Promise<string>; DummyActivity2: (input: string) => Promise<string>; } const { DummyActivity1 } = proxyActivities<Activities>({ startToCloseTimeout: '1 minute', retry: { initialInterval: 1000, maximumInterval: 60, backoffCoefficient: 2, maximumAttempts: 500 }, }) export async function DummyActivity(input: string): Promise<string> { console.log(`starting to execute workflow`) let result: string; try { result = await DummyActivity1(input); } catch (err) { console.log(`failed to call service`) throw new ApplicationFailure(`Error: ${err}`); } return `result ${result}`; } async function run() { const namespace = "default" const connection = await Connection.connect(); const client = new WorkflowClient({ connection, namespace }); console.log( `Starting workflow` ); const handle = await client.start(DummyActivity, { args: ["input"], taskQueue: 'operation-queue', workflowId: 'dummy-activity', }); console.log( `Started Workflow ${handle.workflowId} with RunID ${handle.firstExecutionRunId}` ); console.log(await handle.result()); } run().catch((err) => { console.error(err); process.exit(1); });
错误表现
Temporal UI显示错误:WORKFLOW_TASK_FAILED_CAUSE_WORKFLOW_WORKER_UNHANDLED_FAILURE
解决步骤
Temporal的工作流执行需要对应的Worker处理工作流任务,当前仅启动了处理活动的Go Worker,缺少处理工作流逻辑的TypeScript Worker,导致工作流任务无人处理触发报错。
1. 新增TypeScript Worker代码(worker.ts)
import { Worker, Connection } from '@temporalio/worker'; async function runWorker() { // 连接到Temporal服务器 const connection = await Connection.connect({ address: 'localhost:7233', }); // 创建Worker实例 const worker = await Worker.create({ connection, namespace: 'default', taskQueue: 'operation-queue', // 指定包含工作流定义的文件路径 workflowsPath: require.resolve('./client'), // 活动由Go Worker处理,此处无需注册活动 }); console.log('TypeScript Workflow Worker started'); // 启动Worker await worker.run(); } runWorker().catch(err => { console.error('Workflow Worker failed:', err); process.exit(1); });
2. 运行流程
- 保持Go的Activity Worker运行;
- 启动TypeScript的Workflow Worker:
npx ts-node worker.ts; - 运行TypeScript客户端触发工作流:
npx ts-node client.ts。
此时工作流任务会由TypeScript Worker处理,活动任务由Go Worker处理,即可正常完成工作流执行。
内容的提问来源于stack exchange,提问作者alwesam
相关产品推荐
相关产品推荐

