Skip to content

Commit 143e257

Browse files
authored
Added application error category (#277)
Fixes #242
1 parent 251c16f commit 143e257

File tree

5 files changed

+55
-6
lines changed

5 files changed

+55
-6
lines changed

temporalio/lib/temporalio/converters/failure_converter.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ def to_failure(error, converter)
4545
type: error.type,
4646
non_retryable: error.non_retryable,
4747
details: converter.to_payloads(error.details),
48-
next_retry_delay: Internal::ProtoUtils.seconds_to_duration(error.next_retry_delay)
48+
next_retry_delay: Internal::ProtoUtils.seconds_to_duration(error.next_retry_delay),
49+
category: error.category
4950
)
5051
when Error::TimeoutError
5152
failure.timeout_failure_info = Api::Failure::V1::TimeoutFailureInfo.new(
@@ -132,7 +133,9 @@ def from_failure(failure, converter)
132133
non_retryable: failure.application_failure_info.non_retryable,
133134
next_retry_delay: Internal::ProtoUtils.duration_to_seconds(
134135
failure.application_failure_info.next_retry_delay
135-
)
136+
),
137+
category: Internal::ProtoUtils.enum_to_int(Api::Enums::V1::ApplicationErrorCategory,
138+
failure.application_failure_info.category)
136139
)
137140
elsif failure.timeout_failure_info
138141
Error::TimeoutError.new(

temporalio/lib/temporalio/error/failure.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,43 @@ class ApplicationError < Failure
4646
# @return [Float, nil] Delay in seconds before the next activity retry attempt.
4747
attr_reader :next_retry_delay
4848

49+
# @return [Category] Error category.
50+
attr_reader :category
51+
4952
# Create an application error.
5053
#
5154
# @param message [String] Error message.
5255
# @param details [Array<Object, nil>] Error details.
5356
# @param type [String, nil] Error type.
5457
# @param non_retryable [Boolean] Whether this error should be considered non-retryable.
5558
# @param next_retry_delay [Float, nil] Specific amount of time to delay before next retry.
56-
def initialize(message, *details, type: nil, non_retryable: false, next_retry_delay: nil)
59+
# @param category [Category] Error category.
60+
def initialize(
61+
message,
62+
*details,
63+
type: nil,
64+
non_retryable: false,
65+
next_retry_delay: nil,
66+
category: Category::UNSPECIFIED
67+
)
5768
super(message)
5869
@details = details
5970
@type = type
6071
@non_retryable = non_retryable
6172
@next_retry_delay = next_retry_delay
73+
@category = category
6274
end
6375

6476
# @return [Boolean] Inverse of {non_retryable}.
6577
def retryable?
6678
!@non_retryable
6779
end
80+
81+
# Error category.
82+
module Category
83+
UNSPECIFIED = Api::Enums::V1::ApplicationErrorCategory::APPLICATION_ERROR_CATEGORY_UNSPECIFIED
84+
BENIGN = Api::Enums::V1::ApplicationErrorCategory::APPLICATION_ERROR_CATEGORY_BENIGN
85+
end
6886
end
6987

7088
# Error raised on workflow/activity cancellation.

temporalio/lib/temporalio/internal/worker/activity_worker.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,13 @@ def run_activity(defn, activity, input)
279279
)
280280
else
281281
# General failure
282-
@scoped_logger.warn('Completing activity as failed')
283-
@scoped_logger.warn(e)
282+
log_level = if e.is_a?(Error::ApplicationError) && e.category == Error::ApplicationError::Category::BENIGN
283+
Logger::DEBUG
284+
else
285+
Logger::WARN
286+
end
287+
@scoped_logger.add(log_level, 'Completing activity as failed')
288+
@scoped_logger.add(log_level, e)
284289
Bridge::Api::ActivityResult::ActivityExecutionResult.new(
285290
failed: Bridge::Api::ActivityResult::Failure.new(
286291
failure: @worker.options.client.data_converter.to_failure(e)

temporalio/sig/temporalio/error/failure.rbs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,25 @@ module Temporalio
1616
attr_reader type: String?
1717
attr_reader non_retryable: bool
1818
attr_reader next_retry_delay: duration?
19+
attr_reader category: Category::enum
1920

2021
def initialize: (
2122
String message,
2223
*Object? details,
2324
?type: String?,
2425
?non_retryable: bool,
25-
?next_retry_delay: duration?
26+
?next_retry_delay: duration?,
27+
?category: Category::enum
2628
) -> void
2729

2830
def retryable?: -> bool
31+
32+
module Category
33+
type enum = Integer
34+
35+
UNSPECIFIED: enum
36+
BENIGN: enum
37+
end
2938
end
3039

3140
class CanceledError < Failure

temporalio/test/worker_activity_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,12 @@ def execute(form)
178178
non_retryable: true,
179179
next_retry_delay: 1.23
180180
)
181+
when 'application-benign'
182+
raise Temporalio::Error::ApplicationError.new(
183+
'application-error-benign',
184+
type: 'some-error-type',
185+
category: Temporalio::Error::ApplicationError::Category::BENIGN
186+
)
181187
end
182188
end
183189
end
@@ -203,6 +209,14 @@ def test_failure
203209
assert_equal 'some-error-type', error.cause.cause.type
204210
assert error.cause.cause.non_retryable
205211
assert_equal 1.23, error.cause.cause.next_retry_delay
212+
213+
# Check that benign application error category is set
214+
error = assert_raises(Temporalio::Error::WorkflowFailedError) do
215+
execute_activity(FailureActivity, 'application-benign')
216+
end
217+
assert_equal 'application-error-benign', error.cause.cause.message
218+
assert_equal 'some-error-type', error.cause.cause.type
219+
assert_equal Temporalio::Error::ApplicationError::Category::BENIGN, error.cause.cause.category
206220
end
207221

208222
class UnimplementedExecuteActivity < Temporalio::Activity::Definition

0 commit comments

Comments
 (0)