UNPKG

@temporalio/client

Version:
138 lines 7.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.executionInfoFromRaw = executionInfoFromRaw; exports.decodeCountWorkflowExecutionsResponse = decodeCountWorkflowExecutionsResponse; exports.rethrowKnownErrorTypes = rethrowKnownErrorTypes; const grpc_js_1 = require("@grpc/grpc-js"); const common_1 = require("@temporalio/common"); const payload_search_attributes_1 = require("@temporalio/common/lib/converter/payload-search-attributes"); const time_1 = require("@temporalio/common/lib/time"); const codec_helpers_1 = require("@temporalio/common/lib/internal-non-workflow/codec-helpers"); const proto_1 = require("@temporalio/proto"); function workflowStatusCodeToName(code) { return workflowStatusCodeToNameInternal(code) ?? 'UNKNOWN'; } /** * Intentionally leave out `default` branch to get compilation errors when new values are added */ function workflowStatusCodeToNameInternal(code) { switch (code) { case proto_1.temporal.api.enums.v1.WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_UNSPECIFIED: return 'UNSPECIFIED'; case proto_1.temporal.api.enums.v1.WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_RUNNING: return 'RUNNING'; case proto_1.temporal.api.enums.v1.WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_FAILED: return 'FAILED'; case proto_1.temporal.api.enums.v1.WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_TIMED_OUT: return 'TIMED_OUT'; case proto_1.temporal.api.enums.v1.WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_CANCELED: return 'CANCELLED'; case proto_1.temporal.api.enums.v1.WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_TERMINATED: return 'TERMINATED'; case proto_1.temporal.api.enums.v1.WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_COMPLETED: return 'COMPLETED'; case proto_1.temporal.api.enums.v1.WorkflowExecutionStatus.WORKFLOW_EXECUTION_STATUS_CONTINUED_AS_NEW: return 'CONTINUED_AS_NEW'; } } async function executionInfoFromRaw(raw, dataConverter, rawDataToEmbed) { return { /* eslint-disable @typescript-eslint/no-non-null-assertion */ type: raw.type.name, workflowId: raw.execution.workflowId, runId: raw.execution.runId, taskQueue: raw.taskQueue, status: { code: raw.status, name: workflowStatusCodeToName(raw.status), }, // Safe to convert to number, max history length is 50k, which is much less than Number.MAX_SAFE_INTEGER historyLength: raw.historyLength.toNumber(), // Exact truncation for multi-petabyte histories // historySize === 0 means WFT was generated by pre-1.20.0 server, and the history size is unknown historySize: raw.historySizeBytes?.toNumber() || undefined, startTime: (0, time_1.requiredTsToDate)(raw.startTime, 'startTime'), executionTime: (0, time_1.optionalTsToDate)(raw.executionTime), closeTime: (0, time_1.optionalTsToDate)(raw.closeTime), memo: await (0, codec_helpers_1.decodeMapFromPayloads)(dataConverter, raw.memo?.fields), searchAttributes: (0, payload_search_attributes_1.decodeSearchAttributes)(raw.searchAttributes?.indexedFields), typedSearchAttributes: (0, payload_search_attributes_1.decodeTypedSearchAttributes)(raw.searchAttributes?.indexedFields), parentExecution: raw.parentExecution ? { workflowId: raw.parentExecution.workflowId, runId: raw.parentExecution.runId, } : undefined, rootExecution: raw.rootExecution ? { workflowId: raw.rootExecution.workflowId, runId: raw.rootExecution.runId, } : undefined, raw: rawDataToEmbed, priority: (0, common_1.decodePriority)(raw.priority), }; } function decodeCountWorkflowExecutionsResponse(raw) { return { // Note: lossy conversion of Long to number count: raw.count.toNumber(), groups: raw.groups.map((group) => { return { // Note: lossy conversion of Long to number count: group.count.toNumber(), groupValues: group.groupValues.map((value) => payload_search_attributes_1.searchAttributePayloadConverter.fromPayload(value)), }; }), }; } /** * If the error type can be determined based on embedded grpc error details, * then rethrow the appropriate TypeScript error. Otherwise do nothing. * * This function should be used before falling back to generic error handling * based on grpc error code. Very few error types are currently supported, but * this function will be expanded over time as more server error types are added. */ function rethrowKnownErrorTypes(err) { // We really don't expect multiple error details, but this really is an array, so just in case... for (const entry of getGrpcStatusDetails(err) ?? []) { if (!entry.type_url || !entry.value) continue; const type = entry.type_url.replace(/^type.googleapis.com\//, ''); switch (type) { case 'temporal.api.errordetails.v1.NamespaceNotFoundFailure': { const { namespace } = proto_1.temporal.api.errordetails.v1.NamespaceNotFoundFailure.decode(entry.value); throw new common_1.NamespaceNotFoundError(namespace); } case 'temporal.api.errordetails.v1.MultiOperationExecutionFailure': { // MultiOperationExecutionFailure contains error statuses for multiple // operations. A MultiOperationExecutionAborted error status means that // the corresponding operation was aborted due to an error in one of the // other operations. We rethrow the first operation error that is not // MultiOperationExecutionAborted. const { statuses } = proto_1.temporal.api.errordetails.v1.MultiOperationExecutionFailure.decode(entry.value); for (const status of statuses) { const detail = status.details?.[0]; const statusType = detail?.type_url?.replace(/^type.googleapis.com\//, ''); if (statusType === 'temporal.api.failure.v1.MultiOperationExecutionAborted' || status.code === grpc_js_1.status.OK) { continue; } err.message = status.message ?? err.message; err.code = status.code || err.code; err.details = detail?.value?.toString() || err.details; throw err; } } } } } function getGrpcStatusDetails(err) { const statusBuffer = err.metadata.get('grpc-status-details-bin')?.[0]; if (!statusBuffer || typeof statusBuffer === 'string') { return undefined; } return proto_1.google.rpc.Status.decode(statusBuffer).details; } //# sourceMappingURL=helpers.js.map