diff --git a/internal/adapters/database/db.go b/internal/adapters/database/db.go index 63a39ec..55e3a80 100644 --- a/internal/adapters/database/db.go +++ b/internal/adapters/database/db.go @@ -11,6 +11,18 @@ import ( "gorm.io/gorm" ) +// QueryError is an error that occurred while executing a query. +type QueryError struct { + Query string + Err error +} + +// Error ... +func (e *QueryError) Error() string { return e.Query + ": " + e.Err.Error() } + +// Unwrap ... +func (e *QueryError) Unwrap() error { return e.Err } + type database struct { conn *gorm.DB } @@ -54,34 +66,39 @@ func (d *database) ReadWriteTx(ctx context.Context, fn func(context.Context, por tx.Rollback() } - if err := tx.Error; err != nil && !errors.Is(err, sql.ErrTxDone) { - return err - } - - if err := tx.Commit().Error; err != nil { + if err := tx.Commit().Error; err != nil && !errors.Is(err, sql.ErrTxDone) { return err } return nil } +// NewQueryError returns a new QueryError. +func NewQueryError(query string, err error) *QueryError { + return &QueryError{ + Query: query, + Err: err, + } +} + // ReadTx starts a read only transaction. func (d *database) ReadTx(ctx context.Context, fn func(context.Context, ports.ReadTx) error) error { tx := d.conn.WithContext(ctx).Begin() if tx.Error != nil { - return tx.Error + return NewQueryError("begin read transaction", tx.Error) } - if err := fn(ctx, &datastoreTx{tx}); err != nil { + err := fn(ctx, &datastoreTx{tx}) + if err != nil { tx.Rollback() } - if err := tx.Error; err != nil && !errors.Is(err, sql.ErrTxDone) { - return err + if err := tx.Commit().Error; err != nil && !errors.Is(err, sql.ErrTxDone) { + return NewQueryError("commit read transaction", err) } - if err := tx.Commit().Error; err != nil { - return err + if err != nil { + return NewQueryError("commit read transaction", err) } return nil diff --git a/internal/adapters/handlers/api.go b/internal/adapters/handlers/api.go index 4a86e03..8e035fa 100644 --- a/internal/adapters/handlers/api.go +++ b/internal/adapters/handlers/api.go @@ -2,11 +2,13 @@ package handlers import ( "context" + "errors" "github.com/gofiber/fiber/v2" "github.com/zeiss/knox/internal/controllers" openapi "github.com/zeiss/knox/pkg/apis" "github.com/zeiss/knox/pkg/dto" + "gorm.io/gorm" ) var _ openapi.StrictServerInterface = (*apiHandlers)(nil) @@ -208,6 +210,10 @@ func (a *apiHandlers) GetEnvironmentState(ctx context.Context, request openapi.G query := dto.FromGetEnvironmentStateRequestObject(request) data, err := a.state.GetState(ctx, query) + if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { // the state was not found + return openapi.GetEnvironmentState404JSONResponse{}, nil + } + if err != nil { return nil, fiber.NewError(fiber.StatusNotFound, err.Error()) }