Skip to content

Commit 5f97972

Browse files
authored
feat(workflow): List registered queries in error response when a quer… (#791)
1 parent b57e572 commit 5f97972

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

packages/client/src/workflow-client.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,9 @@ export class WorkflowClient {
611611
},
612612
});
613613
} catch (err) {
614+
if (isServerErrorResponse(err) && err.code === grpcStatus.INVALID_ARGUMENT) {
615+
throw new QueryNotRegisteredError(err.message.replace(/^3 INVALID_ARGUMENT: /, ''), err.code);
616+
}
614617
this.rethrowGrpcError(err, input.workflowExecution, 'Failed to query Workflow');
615618
}
616619
if (response.queryRejected) {
@@ -938,6 +941,13 @@ export class QueryRejectedError extends Error {
938941
}
939942
}
940943

944+
export class QueryNotRegisteredError extends Error {
945+
public readonly name: string = 'QueryNotRegisteredError';
946+
constructor(message: string, public readonly code: grpcStatus) {
947+
super(message);
948+
}
949+
}
950+
941951
function workflowStatusCodeToName(code: temporal.api.enums.v1.WorkflowExecutionStatus): WorkflowExecutionStatusName {
942952
return workflowStatusCodeToNameInternal(code) ?? 'UNKNOWN';
943953
}

packages/test/src/integration-tests.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
ActivityFailure,
44
ApplicationFailure,
55
Connection,
6+
QueryNotRegisteredError,
67
WorkflowClient,
78
WorkflowContinuedAsNewError,
89
WorkflowFailedError,
@@ -391,6 +392,20 @@ export function runIntegrationTests(codec?: PayloadCodec): void {
391392
t.pass();
392393
});
393394

395+
test('query not found', async (t) => {
396+
const { client } = t.context;
397+
const workflow = await client.start(workflows.unblockOrCancel, {
398+
taskQueue: 'test',
399+
workflowId: uuid4(),
400+
});
401+
await workflow.signal(workflows.unblockSignal);
402+
await workflow.result();
403+
await t.throwsAsync(workflow.query('not found'), {
404+
instanceOf: QueryNotRegisteredError,
405+
message: 'Workflow did not register a handler for not found. Registered queries: [__stack_trace isBlocked]',
406+
});
407+
});
408+
394409
test('query and unblock', async (t) => {
395410
const { client } = t.context;
396411
const workflow = await client.start(workflows.unblockOrCancel, {

packages/workflow/src/internals.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,11 @@ export class Activator implements ActivationHandler {
212212
protected queryWorkflowNextHandler({ queryName, args }: QueryInput): Promise<unknown> {
213213
const fn = state.queryHandlers.get(queryName);
214214
if (fn === undefined) {
215+
const knownQueryTypes = [...state.queryHandlers.keys()].join(' ');
215216
// Fail the query
216-
throw new ReferenceError(`Workflow did not register a handler for ${queryName}`);
217+
throw new ReferenceError(
218+
`Workflow did not register a handler for ${queryName}. Registered queries: [${knownQueryTypes}]`
219+
);
217220
}
218221
try {
219222
const ret = fn(...args);

0 commit comments

Comments
 (0)