Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[metadata] handle entity modification error #1540

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions internal/api/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1540,10 +1540,11 @@ func (h *Handler) handlePostDashboard(ctx context.Context, ai accessInfo, dash D
if create {
s = "create"
}
err = fmt.Errorf("cannot %s dashboard: %w", s, err)
if metajournal.IsUserRequestError(err) {
return &DashboardInfo{}, httpErr(http.StatusBadRequest, fmt.Errorf("can't %s dashboard: %w", s, err))
return &DashboardInfo{}, httpErr(http.StatusBadRequest, err)
}
return &DashboardInfo{}, fmt.Errorf("can't %s dashboard: %w", s, err)
return &DashboardInfo{}, err
}
return &DashboardInfo{Dashboard: getDashboardMetaInfo(&dashboard)}, nil
}
Expand Down Expand Up @@ -1617,7 +1618,7 @@ func (h *Handler) handlePostNamespace(ctx context.Context, ai accessInfo, namesp
if create {
s = "create"
}
errReturn := fmt.Errorf("can't %s namespace: %w", s, err)
errReturn := fmt.Errorf("cannot %s namespace: %w", s, err)
if metajournal.IsUserRequestError(err) {
return &NamespaceInfo{}, httpErr(http.StatusBadRequest, errReturn)
}
Expand Down Expand Up @@ -1677,8 +1678,10 @@ func (h *Handler) handlePostMetric(ctx context.Context, ai accessInfo, _ string,
}
resp, err = h.metadataLoader.SaveMetric(ctx, metric, ai.toMetadata())
if err != nil {
err = fmt.Errorf("error creating metric in sqlite engine: %w", err)
log.Println(err.Error())
if metajournal.IsUserRequestError(err) {
errReturn := fmt.Errorf("cannot create metric: %w", err)
return format.MetricMetaValue{}, httpErr(http.StatusBadRequest, errReturn)
}
return format.MetricMetaValue{}, fmt.Errorf("failed to create metric: %w", err)
}
} else {
Expand All @@ -1700,8 +1703,10 @@ func (h *Handler) handlePostMetric(ctx context.Context, ai accessInfo, _ string,
}
resp, err = h.metadataLoader.SaveMetric(ctx, metric, ai.toMetadata())
if err != nil {
err = fmt.Errorf("error saving metric in sqllite: %w", err)
log.Println(err.Error())
if metajournal.IsUserRequestError(err) {
errReturn := fmt.Errorf("cannot update metric: %w", err)
return format.MetricMetaValue{}, httpErr(http.StatusBadRequest, errReturn)
}
return format.MetricMetaValue{}, fmt.Errorf("can't edit metric: %w", err)
}
}
Expand Down
8 changes: 2 additions & 6 deletions internal/metadata/dbv2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,8 @@ func Test_SaveMetric(t *testing.T) {
e, err := db.SaveEntity(context.Background(), "a", 0, 0, "{}", true, false, format.MetricEvent, metadata)
require.NoError(t, err)
require.Equal(t, metadata, e.Metadata)
updates, err := db.JournalEvents(context.Background(), 0, 100)
require.NoError(t, err)
require.Len(t, updates, 1)
m := updates[0]
require.Equal(t, "a", m.Name)
require.Equal(t, "{}", m.Data)
_, err = db.SaveEntity(context.Background(), "a", 0, 0, "{}", true, false, format.MetricEvent, metadata)
require.Error(t, err)
}

func Test_GetOldVersion(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions internal/metadata/rpc_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ func (h *Handler) RawEditEntity(ctx context.Context, hctx *rpc.HandlerContext) (
if errors.Is(err, errInvalidMetricVersion) {
return "", data_model.ErrEntityInvalidVersion
}
if errors.Is(err, errMetricIsExist) {
return "", data_model.ErrEntityExists
}
if err != nil {
return "", fmt.Errorf("failed to create event: %w", err)
}
Expand Down
24 changes: 20 additions & 4 deletions internal/metajournal/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"math"
"time"

"github.com/vkcom/statshouse/internal/data_model"
"go4.org/mem"

"github.com/vkcom/statshouse/internal/data_model/gen2/tlmetadata"
Expand All @@ -39,6 +40,21 @@ func IsUserRequestError(err error) bool {
return errors.Is(err, errorInvalidUserRequest)
}

func wrapSaveEntityError(err error) error {
var rpcErr = &rpc.Error{}
if errors.As(err, &rpcErr) {
switch rpcErr.Code {
case data_model.ErrEntityInvalidVersion.Code:
return errors.Join(errorInvalidUserRequest, fmt.Errorf(data_model.ErrEntityInvalidVersion.Description))
case data_model.ErrEntityExists.Code:
return errors.Join(errorInvalidUserRequest, fmt.Errorf(data_model.ErrEntityExists.Description))
case data_model.ErrEntityNotExists.Code:
return errors.Join(errorInvalidUserRequest, fmt.Errorf(data_model.ErrEntityNotExists.Description))
}
}
return err
}

func NewMetricMetaLoader(client *tlmetadata.Client, loadTimeout time.Duration) *MetricMetaLoader {
return &MetricMetaLoader{
client: client,
Expand Down Expand Up @@ -71,7 +87,7 @@ func (l *MetricMetaLoader) SaveDashboard(ctx context.Context, value format.Dashb
event := tlmetadata.Event{}
err = l.client.EditEntitynew(ctx, editMetricReq, nil, &event)
if err != nil {
return format.DashboardMeta{}, fmt.Errorf("failed to edit metric: %w", err)
return format.DashboardMeta{}, wrapSaveEntityError(err)
}
if event.Id < math.MinInt32 || event.Id > math.MaxInt32 {
return format.DashboardMeta{}, fmt.Errorf("dashboard ID %d assigned by metaengine does not fit into int32 for dashboard %q", event.Id, event.Name)
Expand Down Expand Up @@ -121,7 +137,7 @@ func (l *MetricMetaLoader) SaveMetricsGroup(ctx context.Context, value format.Me
event := tlmetadata.Event{}
err = l.client.EditEntitynew(ctx, editMetricReq, nil, &event)
if err != nil {
return format.MetricsGroup{}, fmt.Errorf("failed to edit group: %w", err)
return format.MetricsGroup{}, wrapSaveEntityError(err)
}
if event.Id < math.MinInt32 || event.Id > math.MaxInt32 {
return g, fmt.Errorf("group ID %d assigned by metaengine does not fit into int32 for group %q", event.Id, event.Name)
Expand Down Expand Up @@ -167,7 +183,7 @@ func (l *MetricMetaLoader) SaveNamespace(ctx context.Context, value format.Names
event := tlmetadata.Event{}
err = l.client.EditEntitynew(ctx, editMetricReq, nil, &event)
if err != nil {
return format.NamespaceMeta{}, fmt.Errorf("failed to edit namespace: %w", err)
return format.NamespaceMeta{}, wrapSaveEntityError(err)
}
if event.Id < math.MinInt32 || event.Id > math.MaxInt32 {
return g, fmt.Errorf("namespace ID %d assigned by metaengine does not fit into int32 for group %q", event.Id, event.Name)
Expand Down Expand Up @@ -260,7 +276,7 @@ func (l *MetricMetaLoader) SaveMetric(ctx context.Context, value format.MetricMe
event := tlmetadata.Event{}
err = l.client.EditEntitynew(ctx, editMetricReq, nil, &event)
if err != nil {
return m, fmt.Errorf("failed to edit metric: %w", err)
return m, wrapSaveEntityError(err)
}
if event.Id < math.MinInt32 || event.Id > math.MaxInt32 {
return m, fmt.Errorf("metric ID %d assigned by metaengine does not fit into int32 for metric %q", event.Id, event.Name)
Expand Down
Loading