lib/temporalio/error.rb
# frozen_string_literal: true require 'temporalio/api' module Temporalio # Superclass for all Temporal errors class Error < StandardError # Whether the error represents some form of cancellation from an activity or workflow. # # @param error [Exception] Error to check. # @return [Boolean] True if some form of canceled, false otherwise. def self.canceled?(error) error.is_a?(CanceledError) || (error.is_a?(ActivityError) && error.cause.is_a?(CanceledError)) || (error.is_a?(ChildWorkflowError) && error.cause.is_a?(CanceledError)) end # @!visibility private def self._with_backtrace_and_cause(err, backtrace:, cause:) if cause # The only way to set a _real_ cause in Ruby is to use `raise`. Even if # you try to override `def cause`, it won't be outputted in situations # where Ruby outputs cause. begin raise(err, err.message, backtrace, cause:) rescue StandardError => e e end else err.set_backtrace(backtrace) if backtrace err end end # Error that is returned from when a workflow is unsuccessful. class WorkflowFailedError < Error # @!visibility private def initialize(message = 'Workflow execution failed') super end end # Error that occurs when a workflow was continued as new. class WorkflowContinuedAsNewError < Error # @return [String] New execution run ID the workflow continued to. attr_reader :new_run_id # @!visibility private def initialize(new_run_id:) super('Workflow execution continued as new') @new_run_id = new_run_id end end # Error that occurs when a query fails. class WorkflowQueryFailedError < Error end # Error that occurs when a query was rejected. class WorkflowQueryRejectedError < Error # @return [Client::WorkflowExecutionStatus] Workflow execution status causing rejection. attr_reader :status # @!visibility private def initialize(status:) super("Query rejected, #{status}") @status = status end end # Error that occurs when an update fails. class WorkflowUpdateFailedError < Error # @!visibility private def initialize super('Workflow update failed') end end # Error that occurs when update RPC call times out or is canceled. # # @note This is not related to any general concept of timing out or cancelling a running update, this is only # related to the client call itself. class WorkflowUpdateRPCTimeoutOrCanceledError < Error # @!visibility private def initialize super('Timeout or cancellation waiting for update') end end # Error when a schedule is already running. class ScheduleAlreadyRunningError < Error # @!visibility private def initialize super('Schedule already running') end end # Error that occurs when an async activity handle tries to heartbeat and the activity is marked as canceled. class AsyncActivityCanceledError < Error # @!visibility private def initialize super('Activity canceled') end end # Error raised by a client for a general RPC failure. class RPCError < Error # @return [Code] Status code for the error. attr_reader :code # @!visibility private def initialize(message, code:, raw_grpc_status:) super(message) @code = code @raw_grpc_status = raw_grpc_status end # @return [Api::Common::V1::GrpcStatus] Status of the gRPC call with details. def grpc_status @grpc_status ||= create_grpc_status end private def create_grpc_status return Api::Common::V1::GrpcStatus.new(code: @code) unless @raw_grpc_status return @raw_grpc_status if @raw_grpc_status.is_a?(Api::Common::V1::GrpcStatus) Api::Common::V1::GrpcStatus.decode(@raw_grpc_status) end # Status code for RPC errors. These are gRPC status codes. module Code OK = 0 CANCELED = 1 # Intentionally one-L while gRPC is two-L UNKNOWN = 2 INVALID_ARGUMENT = 3 DEADLINE_EXCEEDED = 4 NOT_FOUND = 5 ALREADY_EXISTS = 6 PERMISSION_DENIED = 7 RESOURCE_EXHAUSTED = 8 FAILED_PRECONDITION = 9 ABORTED = 10 OUT_OF_RANGE = 11 UNIMPLEMENTED = 12 INTERNAL = 13 UNAVAILABLE = 14 DATA_LOSS = 15 UNAUTHENTICATED = 16 end end end end require 'temporalio/error/failure'