temporalsentryinterceptor

package module
v0.0.0-...-2523356 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2026 License: MIT Imports: 7 Imported by: 0

README

Temporal Sentry Interceptor

A friendly Go library that seamlessly integrates Sentry error tracking with Temporal workflows and activities.

Why This Exists

At Uphold, we rely heavily on Temporal for our critical business workflows. When things go wrong (and they sometimes do!), we needed a clean way to capture errors and panics in Sentry for better observability and debugging. After building this solution for our internal projects, we realized the Go ecosystem was missing a package that really nailed this integration, so we decided to open source this!

Installation

go get github.com/uphold/temporal-sentry-interceptor

Quick Start

package main

import (
	"log"

	"github.com/getsentry/sentry-go"
	temporalsentry "github.com/uphold/temporal-sentry-interceptor"
	"go.temporal.io/sdk/client"
	"go.temporal.io/sdk/interceptor"
	"go.temporal.io/sdk/worker"
)

func main() {
	// Initialize Sentry.
	err := sentry.Init(sentry.ClientOptions{
		Dsn: "your-sentry-dsn",
	})
	if err != nil {
		log.Fatalf("Failed to initialize Sentry: %v", err)
	}

	// Create Temporal client.
	c, err := client.Dial(client.Options{
		/* client options */
	})
	if err != nil {
		log.Fatalln("Unable to create client", err)
	}
	defer c.Close()

	// Create worker with Sentry interceptor.
	w := worker.New(c, "your-task-queue", worker.Options{
		Interceptors: []interceptor.WorkerInterceptor{
			temporalsentry.New(),
		},
	})

	// Register your workflows and activities.
	w.RegisterWorkflow(YourWorkflow)
	w.RegisterActivity(YourActivity)

	// Start the worker.
	err = w.Run(worker.InterruptCh())
	if err != nil {
		log.Fatalln("Unable to start worker", err)
	}
}

Configuration Options

Custom Sentry Scope

Configure how Sentry tags are set:

interceptor := temporalsentry.New(
    temporalsentry.WithConfigureSentryScope(func(
        ctx context.Context,
        request []any,
        activityInfo *activity.Info,
        workflowInfo *workflow.Info,
    ) func(scope *sentry.Scope) {
        return func(scope *sentry.Scope) {
            if workflowInfo != nil {
                scope.SetTag("workflow_type", workflowInfo.WorkflowType.Name)
                scope.SetTag("workflow_id", workflowInfo.WorkflowExecution.ID)
            }
            if activityInfo != nil {
                scope.SetTag("activity_type", activityInfo.ActivityType.Name)
            }
        }
    }),
)
Error and Panic Filtering

Control which errors and panics get reported:

interceptor := temporalsentry.New(
    // Filter workflow errors.
    temporalsentry.WithFilterWorkflowError(func(err error, request []any, info *workflow.Info) bool {
        // Return true to skip reporting this error.
        return errors.Is(err, temporal.ErrCanceled)
    }),

    // Filter workflow panics.
    temporalsentry.WithFilterWorkflowPanic(func(p any, request []any, info *workflow.Info) bool {
        // Return true to skip reporting this panic.
        if panicMsg, ok := p.(string); ok {
            return strings.Contains(panicMsg, "expected panic")
        }
        return false
    }),
)
Custom Activity Options

Configure the activity options for workflow errors and panics:

Important note: Local activities should not take more than the Temporal workflow task timeout (which defaults to 10 seconds), be mindful of that if changing the timeout from its default of 5 seconds. See the difference between Temporal activities and local activities for more information.

interceptor := temporalsentry.New(
    temporalsentry.WithWorkflowErrorActivityOptions(workflow.LocalActivityOptions{
        ScheduleToCloseTimeout: 10 * time.Second,
        RetryPolicy: &temporal.RetryPolicy{
            MaximumAttempts: 3,
        },
    }),
)

Advanced Usage

Multiple Interceptors

You can easily chain multiple interceptors:

Important note: A general rule of thumb is that the Sentry interceptor should go last, as it ensures that it wraps the entire call stack and that other interceptors that might handle errors or recover from panics don't erase them.

w := worker.New(c, "task-queue", worker.Options{
    Interceptors: []interceptor.WorkerInterceptor{
        yourCustomInterceptor.New(),
        temporalsentry.New(/* your options */), // important to place the Sentry interceptor last!
    },
})

Note on Sentry configuration

It is recommended that Sentry's HTTPSyncTransport is not used, as all calls to sentry.CaptureException and sentry.Recover will block on the request being captured to Sentry if that transport is used. If the application's network connection to Sentry's servers is unreliable or unavailable it will cause issues due to the constraints that Temporal's local activities have of not being able to run for more than the amount of time a workflow task can (default is 10 seconds).

Contributing

We welcome contributions! Whether it's bug reports, feature requests, or pull requests!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push fork feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

  • Issues: Found a bug? Open an issue
  • Feature Requests: Have an idea? We'd love to hear it!

Made with ❤️ by the team at Uphold uphold logo

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ConfigureSentryScopeFunc

type ConfigureSentryScopeFunc = func(
	ctx context.Context, request []any, eventName string, activityInfo *activity.Info, workflowInfo *workflow.Info,
) func(scope *sentry.Scope)

ConfigureSentryScopeFunc defines a function to configure Sentry scope with context and request data.

type FilterActivityErrorFunc

type FilterActivityErrorFunc = func(err error, request []any, info *activity.Info) bool

FilterActivityErrorFunc defines a function to filter activity errors before reporting to Sentry.

type FilterActivityPanicFunc

type FilterActivityPanicFunc = func(p any, request []any, info *activity.Info) bool

FilterActivityPanicFunc defines a function to filter activity panics before reporting to Sentry.

type FilterWorkflowErrorFunc

type FilterWorkflowErrorFunc = func(err error, request []any, info *workflow.Info) bool

FilterWorkflowErrorFunc defines a function to filter workflow errors before reporting to Sentry.

type FilterWorkflowPanicFunc

type FilterWorkflowPanicFunc = func(p any, request []any, info *workflow.Info) bool

FilterWorkflowPanicFunc defines a function to filter workflow panics before reporting to Sentry.

type Option

type Option = func(*options)

Option defines a configuration option for the interceptor.

func WithConfigureSentryScope

func WithConfigureSentryScope(configureSentryScope ConfigureSentryScopeFunc) Option

WithConfigureSentryScope sets a custom function to configure Sentry scope.

func WithFilterActivityError

func WithFilterActivityError(filterActivityError FilterActivityErrorFunc) Option

WithFilterActivityError sets a filter function for activity errors.

func WithFilterActivityPanic

func WithFilterActivityPanic(filterActivityPanic FilterActivityPanicFunc) Option

WithFilterActivityPanic sets a filter function for activity panics.

func WithFilterWorkflowError

func WithFilterWorkflowError(filterWorkflowError FilterWorkflowErrorFunc) Option

WithFilterWorkflowError sets a filter function for workflow errors.

func WithFilterWorkflowPanic

func WithFilterWorkflowPanic(filterWorkflowPanic FilterWorkflowPanicFunc) Option

WithFilterWorkflowPanic sets a filter function for workflow panics.

func WithWorkflowErrorActivityOptions

func WithWorkflowErrorActivityOptions(workflowErrorActivityOptions workflow.LocalActivityOptions) Option

WithWorkflowErrorActivityOptions sets custom activity options for error reporting.

func WithWorkflowPanicActivityOptions

func WithWorkflowPanicActivityOptions(workflowPanicActivityOptions workflow.LocalActivityOptions) Option

WithWorkflowPanicActivityOptions sets custom activity options for panic reporting.

type ReportErrorInput

type ReportErrorInput struct {
	Error        error
	EventName    string
	Request      []any
	ActivityInfo *activity.Info
	WorkflowInfo *workflow.Info
}

ReportErrorInput contains data needed to report an error to Sentry.

type ReportPanicInput

type ReportPanicInput struct {
	Panic        any
	EventName    string
	Request      []any
	ActivityInfo *activity.Info
	WorkflowInfo *workflow.Info
}

ReportPanicInput contains data needed to report a panic to Sentry.

type TemporalActivityInterceptor

type TemporalActivityInterceptor struct {
	interceptor.ActivityInboundInterceptorBase
	// contains filtered or unexported fields
}

TemporalActivityInterceptor provides Sentry error and panic reporting for Temporal activity executions.

func (*TemporalActivityInterceptor) ExecuteActivity

ExecuteActivity intercepts activity execution and reports errors/panics to Sentry.

type TemporalWorkerInterceptor

type TemporalWorkerInterceptor struct {
	*interceptor.WorkerInterceptorBase
	// contains filtered or unexported fields
}

TemporalWorkerInterceptor provides Sentry error and panic reporting for Temporal workflows and activities.

func New

func New(opts ...Option) *TemporalWorkerInterceptor

New creates a new TemporalWorkerInterceptor with the provided options.

Note: This interceptor uses local activities for error reporting which must complete within the workflow task timeout (default 10s). The default timeout is 5s to provide a safety margin. Learn more about local activities vs activities here: https://community.temporal.io/t/local-activity-vs-activity/290/3.

func (TemporalWorkerInterceptor) InterceptActivity

InterceptActivity creates and returns an activity interceptor with Sentry integration.

func (TemporalWorkerInterceptor) InterceptWorkflow

InterceptWorkflow creates and returns a workflow interceptor with Sentry integration.

type TemporalWorkflowInterceptor

type TemporalWorkflowInterceptor struct {
	interceptor.WorkflowInboundInterceptorBase
	// contains filtered or unexported fields
}

TemporalWorkflowInterceptor provides Sentry error and panic reporting for Temporal workflow executions.

func (*TemporalWorkflowInterceptor) ExecuteUpdate

ExecuteUpdate intercepts update execution and reports errors/panics to Sentry.

func (*TemporalWorkflowInterceptor) ExecuteWorkflow

ExecuteWorkflow intercepts workflow execution and reports errors/panics to Sentry.

func (*TemporalWorkflowInterceptor) HandleQuery

HandleQuery intercepts query handling and reports errors/panics to Sentry.

func (*TemporalWorkflowInterceptor) HandleSignal

HandleSignal intercepts signal handling and reports errors/panics to Sentry.

func (*TemporalWorkflowInterceptor) ValidateUpdate

ValidateUpdate intercepts update validation and reports errors/panics to Sentry.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL