96 lines
2.8 KiB
Go
96 lines
2.8 KiB
Go
package errorrecord
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.toki-labs.com/toki/ariadne/internal/domain/organization"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
const SchemaVersionV1 = "ariadne.error-event.v1"
|
|
|
|
// Event is Ariadne's normalized domain representation of an incoming error.
|
|
// OrganizationID, ProjectID and IngestionSourceID are resolved from
|
|
// authenticated ingestion credentials and are intentionally not part of the
|
|
// external error-event payload.
|
|
type Event struct {
|
|
SchemaVersion string
|
|
EventID string
|
|
OrganizationID organization.ID
|
|
ProjectID string
|
|
IngestionSourceID string
|
|
OccurredAt time.Time
|
|
Source Source
|
|
Error ErrorDetail
|
|
Runtime *Runtime
|
|
Fingerprint string
|
|
Labels map[string]string
|
|
}
|
|
|
|
type Source struct {
|
|
System string
|
|
Service string
|
|
Environment string
|
|
Component string
|
|
}
|
|
|
|
type ErrorDetail struct {
|
|
Type string
|
|
Code string
|
|
Message string
|
|
StackTrace string
|
|
Cause string
|
|
}
|
|
|
|
type Runtime struct {
|
|
Host string
|
|
Process string
|
|
Version string
|
|
CommitSHA string
|
|
}
|
|
|
|
func (event Event) Validate() error {
|
|
var validationErrors []error
|
|
|
|
if event.SchemaVersion != SchemaVersionV1 {
|
|
validationErrors = append(validationErrors, fmt.Errorf("unsupported schema version %q", event.SchemaVersion))
|
|
}
|
|
if strings.TrimSpace(event.EventID) == "" {
|
|
validationErrors = append(validationErrors, errors.New("event id is required"))
|
|
}
|
|
if err := event.OrganizationID.Validate(); err != nil {
|
|
validationErrors = append(validationErrors, fmt.Errorf("organization id: %w", err))
|
|
}
|
|
if _, err := uuid.Parse(event.ProjectID); err != nil {
|
|
validationErrors = append(validationErrors, fmt.Errorf("project id: %w", err))
|
|
}
|
|
if _, err := uuid.Parse(event.IngestionSourceID); err != nil {
|
|
validationErrors = append(
|
|
validationErrors,
|
|
fmt.Errorf("ingestion source id: %w", err),
|
|
)
|
|
}
|
|
if event.OccurredAt.IsZero() {
|
|
validationErrors = append(validationErrors, errors.New("occurred at is required"))
|
|
}
|
|
if strings.TrimSpace(event.Source.System) == "" {
|
|
validationErrors = append(validationErrors, errors.New("source system is required"))
|
|
}
|
|
if strings.TrimSpace(event.Source.Service) == "" {
|
|
validationErrors = append(validationErrors, errors.New("source service is required"))
|
|
}
|
|
if strings.TrimSpace(event.Source.Environment) == "" {
|
|
validationErrors = append(validationErrors, errors.New("source environment is required"))
|
|
}
|
|
if strings.TrimSpace(event.Error.Type) == "" {
|
|
validationErrors = append(validationErrors, errors.New("error type is required"))
|
|
}
|
|
if strings.TrimSpace(event.Error.Message) == "" {
|
|
validationErrors = append(validationErrors, errors.New("error message is required"))
|
|
}
|
|
|
|
return errors.Join(validationErrors...)
|
|
}
|