mirror of
https://github.com/temporalio/skill-temporal-developer.git
synced 2026-09-14 13:52:58 +08:00
44eba4e91c
* Add .NET reference files for temporal-developer skill Created 11 .NET reference files covering: dotnet.md (overview/quick start), patterns.md, determinism.md, determinism-protection.md, error-handling.md, testing.md, versioning.md, observability.md, data-handling.md, gotchas.md, and advanced-features.md. Follows Python/TypeScript patterns with .NET-specific content for Task determinism, CancellationToken, dependency injection, etc. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix .NET alignment issues from self-review - dotnet.md: Reduce Determinism Rules section to brief cross-reference (was duplicating determinism.md content) - patterns.md: Add ParentClosePolicy to Child Workflows example - gotchas.md: Add missing "Heartbeat Timeout Too Short" subsection - versioning.md: Add missing Key Concepts, Deployment Strategies, Query Filters, PINNED/AUTO_UPGRADE guidance, CLI examples - advanced-features.md: Add worker-level heading for exception types Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix .NET correctness issues from verification pass - patterns.md: Fix cancellation pattern to use official TemporalException.IsCanceledException(e) with detached CancellationTokenSource - advanced-features.md: Fix DI hosting example to use official AddHostedTemporalWorker(clientTargetHost:, clientNamespace:, taskQueue:) pattern Verified against official SDK README, API docs, and temporal-docs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Update supported language references to include .NET - SKILL.md: Add "Temporal .NET" and "Temporal C#" trigger phrases, update overview to mention .NET, add .NET entry in getting started - core/determinism.md: Add .NET entry in SDK Protection Mechanisms Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Edits to advanced features * edits to determinism protection, and move the .editorconfig section * missed one * edit determinism.md * edit error-handling.md * edit gotchas.md * edit patterns.md * edit versioning.md * edit observability.md * fix metrics * self-review round 1 * minor correctness fixed * Update references/dotnet/patterns.md Co-authored-by: Justin Anderson <44687433+jmaeagle99@users.noreply.github.com> * address comments, clarify reference to earlier code snippet * clarify that operations are forbidden IN WORKFLOWS * cleanup workflow cancellation handling example * add task token retrieval comment * update .net requirements * Fix propagation of workflow cancellation --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Justin Anderson <44687433+jmaeagle99@users.noreply.github.com>
4.1 KiB
4.1 KiB
Python SDK Error Handling
Overview
The Python SDK uses ApplicationError for application-specific errors and provides comprehensive retry policy configuration. Generally, the following information about errors and retryability applies across activities, child workflows and Nexus operations.
Application Errors
from temporalio import activity
from temporalio.exceptions import ApplicationError
@activity.defn
async def validate_order(order: Order) -> None:
if not order.is_valid():
raise ApplicationError(
"Invalid order",
type="ValidationError",
)
Non-Retryable Errors
from dataclasses import dataclass
from temporalio import activity
from temporalio.exceptions import ApplicationError
@dataclass
class ChargeCardInput:
card_number: str
amount: float
@activity.defn
async def charge_card(input: ChargeCardInput) -> str:
if not is_valid_card(input.card_number):
raise ApplicationError(
"Permanent failure - invalid credit card",
type="PaymentError",
non_retryable=True, # Will not retry activity
)
return await process_payment(input.card_number, input.amount)
Handling Activity Errors
from datetime import timedelta
from temporalio import workflow
from temporalio.exceptions import ActivityError, ApplicationError, is_cancelled_exception
@workflow.defn
class MyWorkflow:
@workflow.run
async def run(self) -> str:
try:
return await workflow.execute_activity(
risky_activity,
start_to_close_timeout=timedelta(minutes=5),
)
except ActivityError as e:
# Let cancellation propagate so the workflow is canceled, not failed
if is_cancelled_exception(e):
raise
workflow.logger.error(f"Activity failed: {e}")
# Handle or re-raise
raise ApplicationError("Workflow failed due to activity error")
Retry Policy Configuration
from datetime import timedelta
from temporalio import workflow
from temporalio.common import RetryPolicy
@workflow.defn
class MyWorkflow:
@workflow.run
async def run(self) -> str:
result = await workflow.execute_activity(
my_activity,
start_to_close_timeout=timedelta(minutes=10),
retry_policy=RetryPolicy(
maximum_interval=timedelta(minutes=1),
maximum_attempts=5,
non_retryable_error_types=["ValidationError", "PaymentError"],
),
)
return result
Only set options such as maximum_interval, maximum_attempts etc. if you have a domain-specific reason to. If not, prefer to leave them at their defaults.
Timeout Configuration
from datetime import timedelta
from temporalio import workflow
@workflow.defn
class MyWorkflow:
@workflow.run
async def run(self) -> str:
return await workflow.execute_activity(
my_activity,
start_to_close_timeout=timedelta(minutes=5), # Single attempt
schedule_to_close_timeout=timedelta(minutes=30), # Including retries
heartbeat_timeout=timedelta(minutes=2), # Between heartbeats
)
Workflow Failure
from temporalio import workflow
from temporalio.exceptions import ApplicationError
@workflow.defn
class MyWorkflow:
@workflow.run
async def run(self) -> str:
if some_condition:
raise ApplicationError(
"Cannot process order",
type="BusinessError",
)
return "success"
Note: Do not use non_retryable= with ApplicationError inside a worklow (as opposed to an activity).
Best Practices
- Use specific error types for different failure modes
- Mark permanent failures as non-retryable
- Configure appropriate retry policies
- Log errors before re-raising
- Use
ActivityErrorto catch activity failures in workflows - Design code to be idempotent for safe retries (see more at
references/core/patterns.md)