encoredev / encore

Open Source Development Platform for building robust type-safe distributed systems with declarative infrastructure
https://encore.dev
Mozilla Public License 2.0
7.65k stars 323 forks source link

Calls not being traced if validation fails #1078

Open melkstam opened 8 months ago

melkstam commented 8 months ago

We've had a few cases where traces for calls would not show up, neither locally, encore or our own cloud. To the best of our understanding, it happens when an internal parameter validation function returns an error.

Here is an example which reproduces the issue. When calling hello.World with failValidation: true, the following app does not gets any traced logged.

package hello

import (
    "context"

    "encore.dev/beta/errs"
)

type WorldParams struct {
    FailValidation bool `json:"failValidation"`
}

type WorldResponse struct {
    Message string `json:"message"`
}

//encore:api public
func World(ctx context.Context, in *WorldParams) (*WorldResponse, error) {

    err := WorldInteral(ctx, &WorldInternalParams{
        FailValidation: in.FailValidation,
    })
    if err != nil {
        return nil, err
    }

    return &WorldResponse{Message: "Hello, encore!"}, nil
}

type WorldInternalParams struct {
    FailValidation bool `json:"failValidation"`
}

func (p *WorldInternalParams) Validate() error {
    if p.FailValidation {
        return &errs.Error{Code: errs.InvalidArgument}
    }
    return nil
}

// encore:api private
func WorldInteral(ctx context.Context, in *WorldInternalParams) error {
    return nil
}
melkstam commented 1 week ago

For some more context, this also happens for subscriber handlers. The following code doesn't record any traces:

// Service hello implements a simple hello world REST API.
package hello

import (
    "context"

    "encore.dev/beta/errs"
    "encore.dev/pubsub"
)

type TestTopicEvent struct{}

var TestTopic = pubsub.NewTopic[TestTopicEvent](
    "test-topic",
    pubsub.TopicConfig{
        DeliveryGuarantee: pubsub.AtLeastOnce,
    },
)

//encore:api public
func PublishEvent(ctx context.Context) error {
    _, err := TestTopic.Publish(ctx, TestTopicEvent{})
    if err != nil {
        return err
    }

    return nil
}

var _ = pubsub.NewSubscription(
    TestTopic,
    "handle-test-event",
    pubsub.SubscriptionConfig[TestTopicEvent]{
        Handler: HandleTestEvent,
    },
)

func HandleTestEvent(ctx context.Context, event TestTopicEvent) error {
    return InternalEndpoint(ctx, &InternalEndpointParams{})
}

type InternalEndpointParams struct{}

func (p *InternalEndpointParams) Validate() error {
    return &errs.Error{Code: errs.InvalidArgument, Message: "invalid argument"}
}

// encore:api private
func InternalEndpoint(ctx context.Context, params *InternalEndpointParams) error {
    return &errs.Error{Code: errs.Unimplemented, Message: "not implemented"}
}

https://github.com/user-attachments/assets/c9bd3fb7-2580-43c2-9281-36d0f095f696