fix: replace fmt.Errorf with signoz/pkg/errors and update golangci-li… (#9373)
This PR fulfills the requirements of #9069 by: - Adding a golangci-lint directive (forbidigo) to disallow all fmt.Errorf usages. - Replacing existing fmt.Errorf instances with structured errors from github.com/SigNoz/signoz/pkg/errors for consistent error classification and lint compliance. - Verified lint and build integrity.
This commit is contained in:
@@ -32,6 +32,10 @@ linters-settings:
|
||||
iface:
|
||||
enable:
|
||||
- identical
|
||||
forbidigo:
|
||||
forbid:
|
||||
- fmt.Errorf
|
||||
- ^(fmt\.Print.*|print|println)$
|
||||
issues:
|
||||
exclude-dirs:
|
||||
- "pkg/query-service"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package licensing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/licensing"
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@ func Config(pollInterval time.Duration, failureThreshold int) licensing.Config {
|
||||
once.Do(func() {
|
||||
config = licensing.Config{PollInterval: pollInterval, FailureThreshold: failureThreshold}
|
||||
if err := config.Validate(); err != nil {
|
||||
panic(fmt.Errorf("invalid licensing config: %w", err))
|
||||
panic(errors.WrapInternalf(err, errors.CodeInternal, "invalid licensing config"))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package zeus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
neturl "net/url"
|
||||
"sync"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/zeus"
|
||||
)
|
||||
|
||||
@@ -24,17 +24,17 @@ func Config() zeus.Config {
|
||||
once.Do(func() {
|
||||
parsedURL, err := neturl.Parse(url)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("invalid zeus URL: %w", err))
|
||||
panic(errors.WrapInternalf(err, errors.CodeInternal, "invalid zeus URL"))
|
||||
}
|
||||
|
||||
deprecatedParsedURL, err := neturl.Parse(deprecatedURL)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("invalid zeus deprecated URL: %w", err))
|
||||
panic(errors.WrapInternalf(err, errors.CodeInternal, "invalid zeus deprecated URL"))
|
||||
}
|
||||
|
||||
config = zeus.Config{URL: parsedURL, DeprecatedURL: deprecatedParsedURL}
|
||||
if err := config.Validate(); err != nil {
|
||||
panic(fmt.Errorf("invalid zeus config: %w", err))
|
||||
panic(errors.WrapInternalf(err, errors.CodeInternal, "invalid zeus config"))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
commoncfg "github.com/prometheus/common/config"
|
||||
"github.com/prometheus/common/model"
|
||||
|
||||
@@ -145,7 +145,7 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
|
||||
} else {
|
||||
content, err := os.ReadFile(n.conf.WebhookURLFile)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("read webhook_url_file: %w", err)
|
||||
return false, errors.WrapInternalf(err, errors.CodeInternal, "read webhook_url_file")
|
||||
}
|
||||
url = strings.TrimSpace(string(content))
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ package alertmanagerserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/prometheus/alertmanager/types"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/alertmanager/types"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/alertmanager/alertmanagernotify"
|
||||
"github.com/SigNoz/signoz/pkg/alertmanager/nfmanager"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
@@ -395,7 +395,7 @@ func (server *Server) TestAlert(ctx context.Context, receiversMap map[*alertmana
|
||||
receiver, err := server.alertmanagerConfig.GetReceiver(receiverName)
|
||||
if err != nil {
|
||||
mu.Lock()
|
||||
errs = append(errs, fmt.Errorf("failed to get receiver %q: %w", receiverName, err))
|
||||
errs = append(errs, errors.WrapInternalf(err, errors.CodeInternal, "failed to get receiver %q", receiverName))
|
||||
mu.Unlock()
|
||||
return nil // Return nil to continue processing other goroutines
|
||||
}
|
||||
@@ -412,7 +412,7 @@ func (server *Server) TestAlert(ctx context.Context, receiversMap map[*alertmana
|
||||
)
|
||||
if err != nil {
|
||||
mu.Lock()
|
||||
errs = append(errs, fmt.Errorf("receiver %q test failed: %w", receiverName, err))
|
||||
errs = append(errs, errors.WrapInternalf(err, errors.CodeInternal, "receiver %q test failed", receiverName))
|
||||
mu.Unlock()
|
||||
}
|
||||
return nil // Return nil to continue processing other goroutines
|
||||
|
||||
@@ -2,9 +2,9 @@ package nfmanagertest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/alertmanagertypes"
|
||||
"github.com/prometheus/common/model"
|
||||
)
|
||||
@@ -94,7 +94,7 @@ func (m *MockNotificationManager) CreateRoutePolicy(ctx context.Context, orgID s
|
||||
}
|
||||
|
||||
if route == nil {
|
||||
return fmt.Errorf("route cannot be nil")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "route cannot be nil")
|
||||
}
|
||||
|
||||
if err := route.Validate(); err != nil {
|
||||
@@ -116,14 +116,14 @@ func (m *MockNotificationManager) CreateRoutePolicies(ctx context.Context, orgID
|
||||
}
|
||||
|
||||
if len(routes) == 0 {
|
||||
return fmt.Errorf("routes cannot be empty")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "routes cannot be empty")
|
||||
}
|
||||
for i, route := range routes {
|
||||
if route == nil {
|
||||
return fmt.Errorf("route at index %d cannot be nil", i)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "route at index %d cannot be nil", i)
|
||||
}
|
||||
if err := route.Validate(); err != nil {
|
||||
return fmt.Errorf("route at index %d: %s", i, err.Error())
|
||||
return errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "route at index %d", i)
|
||||
}
|
||||
}
|
||||
for _, route := range routes {
|
||||
@@ -142,13 +142,13 @@ func (m *MockNotificationManager) GetRoutePolicyByID(ctx context.Context, orgID
|
||||
}
|
||||
|
||||
if routeID == "" {
|
||||
return nil, fmt.Errorf("routeID cannot be empty")
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "routeID cannot be empty")
|
||||
}
|
||||
|
||||
routeKey := getKey(orgID, routeID)
|
||||
route, exists := m.routes[routeKey]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("route with ID %s not found", routeID)
|
||||
return nil, errors.NewNotFoundf(errors.CodeNotFound, "route with ID %s not found", routeID)
|
||||
}
|
||||
|
||||
return route, nil
|
||||
@@ -161,7 +161,7 @@ func (m *MockNotificationManager) GetAllRoutePolicies(ctx context.Context, orgID
|
||||
}
|
||||
|
||||
if orgID == "" {
|
||||
return nil, fmt.Errorf("orgID cannot be empty")
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "orgID cannot be empty")
|
||||
}
|
||||
|
||||
var routes []*alertmanagertypes.RoutePolicy
|
||||
@@ -182,13 +182,13 @@ func (m *MockNotificationManager) DeleteRoutePolicy(ctx context.Context, orgID s
|
||||
}
|
||||
|
||||
if routeID == "" {
|
||||
return fmt.Errorf("routeID cannot be empty")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "routeID cannot be empty")
|
||||
}
|
||||
|
||||
routeKey := getKey(orgID, routeID)
|
||||
route, exists := m.routes[routeKey]
|
||||
if !exists {
|
||||
return fmt.Errorf("route with ID %s not found", routeID)
|
||||
return errors.NewNotFoundf(errors.CodeNotFound, "route with ID %s not found", routeID)
|
||||
}
|
||||
delete(m.routes, routeKey)
|
||||
|
||||
@@ -217,11 +217,11 @@ func (m *MockNotificationManager) DeleteAllRoutePoliciesByName(ctx context.Conte
|
||||
}
|
||||
|
||||
if orgID == "" {
|
||||
return fmt.Errorf("orgID cannot be empty")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "orgID cannot be empty")
|
||||
}
|
||||
|
||||
if name == "" {
|
||||
return fmt.Errorf("name cannot be empty")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "name cannot be empty")
|
||||
}
|
||||
|
||||
nameKey := getKey(orgID, name)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -20,8 +21,9 @@ func NewUri(input string) (Uri, error) {
|
||||
submatches := uriRegex.FindStringSubmatch(input)
|
||||
|
||||
if len(submatches) != 3 {
|
||||
return Uri{}, fmt.Errorf("invalid uri: %q", input)
|
||||
return Uri{}, errors.NewInvalidInputf(errors.CodeInvalidInput, "invalid uri: %q", input)
|
||||
}
|
||||
|
||||
return Uri{
|
||||
scheme: submatches[1],
|
||||
value: submatches[2],
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
@@ -28,7 +27,7 @@ type Code struct{ s string }
|
||||
|
||||
func NewCode(s string) (Code, error) {
|
||||
if !codeRegex.MatchString(s) {
|
||||
return Code{}, fmt.Errorf("invalid code: %v", s)
|
||||
return Code{}, NewInvalidInputf(CodeInvalidInput, "invalid code: %v", s)
|
||||
}
|
||||
|
||||
return Code{s: s}, nil
|
||||
|
||||
@@ -39,7 +39,7 @@ func (b *base) Error() string {
|
||||
return b.e.Error()
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s(%s): %s", b.t.s, b.c, b.m)
|
||||
return b.m
|
||||
}
|
||||
|
||||
// New returns a base error. It requires type, code and message as input.
|
||||
|
||||
@@ -17,7 +17,7 @@ func TestNewf(t *testing.T) {
|
||||
typ := typ{"test-error"}
|
||||
err := Newf(typ, MustNewCode("test_code"), "test error info with %s", "string")
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, "test-error(test_code): test error info with string", err.Error())
|
||||
assert.Equal(t, "test error info with string", err.Error())
|
||||
}
|
||||
|
||||
func TestWrapf(t *testing.T) {
|
||||
@@ -29,10 +29,10 @@ func TestWrapf(t *testing.T) {
|
||||
func TestError(t *testing.T) {
|
||||
typ := typ{"test-error"}
|
||||
err1 := New(typ, MustNewCode("test_code"), "info for err1")
|
||||
assert.Equal(t, "test-error(test_code): info for err1", err1.Error())
|
||||
assert.Equal(t, "info for err1", err1.Error())
|
||||
|
||||
err2 := Wrapf(err1, typ, MustNewCode("test_code"), "info for err2")
|
||||
assert.Equal(t, "test-error(test_code): info for err1", err2.Error())
|
||||
assert.Equal(t, "info for err1", err2.Error())
|
||||
}
|
||||
|
||||
func TestUnwrapb(t *testing.T) {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package factory
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"regexp"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
)
|
||||
|
||||
var _ slog.LogValuer = (Name{})
|
||||
@@ -29,7 +30,7 @@ func (n Name) String() string {
|
||||
// NewName creates a new name.
|
||||
func NewName(name string) (Name, error) {
|
||||
if !nameRegex.MatchString(name) {
|
||||
return Name{}, fmt.Errorf("invalid factory name %q", name)
|
||||
return Name{}, errors.NewInvalidInputf(errors.CodeInvalidInput, "invalid factory name %q", name)
|
||||
}
|
||||
return Name{name: name}, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package factory
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
)
|
||||
|
||||
// Named is implemented by all types of factories.
|
||||
type Named interface {
|
||||
@@ -18,7 +20,11 @@ func NewNamedMap[T Named](factories ...T) (NamedMap[T], error) {
|
||||
fmap := make(map[Name]T)
|
||||
for _, factory := range factories {
|
||||
if _, ok := fmap[factory.Name()]; ok {
|
||||
return NamedMap[T]{}, fmt.Errorf("cannot build factory map, duplicate name %q found", factory.Name())
|
||||
return NamedMap[T]{}, errors.NewInvalidInputf(
|
||||
errors.CodeInvalidInput,
|
||||
"cannot build factory map, duplicate name %q found",
|
||||
factory.Name(),
|
||||
)
|
||||
}
|
||||
|
||||
fmap[factory.Name()] = factory
|
||||
@@ -47,7 +53,11 @@ func (n *NamedMap[T]) Get(namestr string) (t T, err error) {
|
||||
|
||||
factory, ok := n.factories[name]
|
||||
if !ok {
|
||||
err = fmt.Errorf("factory %q not found or not registered", name)
|
||||
err = errors.NewNotFoundf(
|
||||
errors.CodeNotFound,
|
||||
"factory %q not found or not registered",
|
||||
name,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -60,7 +70,12 @@ func (n *NamedMap[T]) Get(namestr string) (t T, err error) {
|
||||
func (n *NamedMap[T]) Add(factory T) (err error) {
|
||||
name := factory.Name()
|
||||
if _, ok := n.factories[name]; ok {
|
||||
return fmt.Errorf("factory %q already exists", name)
|
||||
return errors.Newf(
|
||||
errors.TypeAlreadyExists,
|
||||
errors.CodeAlreadyExists,
|
||||
"factory %q already exists",
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
n.factories[name] = factory
|
||||
|
||||
@@ -2,10 +2,11 @@ package middleware
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -100,7 +101,7 @@ func (writer *nonFlushingBadResponseLoggingWriter) Hijack() (net.Conn, *bufio.Re
|
||||
if ok {
|
||||
return hj.Hijack()
|
||||
}
|
||||
return nil, nil, fmt.Errorf("cannot cast underlying response writer to Hijacker")
|
||||
return nil, nil, errors.NewInternalf(errors.CodeInternal, "cannot cast underlying response writer to Hijacker")
|
||||
}
|
||||
|
||||
func (writer *nonFlushingBadResponseLoggingWriter) StatusCode() int {
|
||||
|
||||
@@ -2,11 +2,11 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
)
|
||||
|
||||
@@ -21,11 +21,11 @@ type Server struct {
|
||||
|
||||
func New(logger *slog.Logger, cfg Config, handler http.Handler) (*Server, error) {
|
||||
if handler == nil {
|
||||
return nil, fmt.Errorf("cannot build http server, handler is required")
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "cannot build http server, handler is required")
|
||||
}
|
||||
|
||||
if logger == nil {
|
||||
return nil, fmt.Errorf("cannot build http server, logger is required")
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "cannot build http server, logger is required")
|
||||
}
|
||||
|
||||
srv := &http.Server{
|
||||
|
||||
@@ -40,10 +40,10 @@ func (rws readerWithServer) Shutdown(ctx context.Context) error {
|
||||
func prometheusReaderWithCustomRegistry(ctx context.Context, prometheusConfig *contribsdkconfig.Prometheus, customRegistry *prometheus.Registry) (sdkmetric.Reader, error) {
|
||||
var opts []otelprom.Option
|
||||
if prometheusConfig.Host == nil {
|
||||
return nil, fmt.Errorf("host must be specified")
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "host must be specified")
|
||||
}
|
||||
if prometheusConfig.Port == nil {
|
||||
return nil, fmt.Errorf("port must be specified")
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "port must be specified")
|
||||
}
|
||||
if prometheusConfig.WithoutScopeInfo != nil && *prometheusConfig.WithoutScopeInfo {
|
||||
opts = append(opts, otelprom.WithoutScopeInfo())
|
||||
|
||||
@@ -3,10 +3,10 @@ package implsavedview
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/modules/savedview"
|
||||
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
@@ -32,7 +32,7 @@ func (module *module) GetViewsForFilters(ctx context.Context, orgID string, sour
|
||||
err = module.sqlstore.BunDB().NewSelect().Model(&views).Where("org_id = ? AND source_page = ? AND category LIKE ? AND name LIKE ?", orgID, sourcePage, "%"+category+"%", "%"+name+"%").Scan(ctx)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in getting saved views: %s", err.Error())
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "error in getting saved views")
|
||||
}
|
||||
|
||||
var savedViews []*v3.SavedView
|
||||
@@ -40,7 +40,7 @@ func (module *module) GetViewsForFilters(ctx context.Context, orgID string, sour
|
||||
var compositeQuery v3.CompositeQuery
|
||||
err = json.Unmarshal([]byte(view.Data), &compositeQuery)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in unmarshalling explorer query data: %s", err.Error())
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "error in unmarshalling explorer query data: %s", err.Error())
|
||||
}
|
||||
savedViews = append(savedViews, &v3.SavedView{
|
||||
ID: view.ID,
|
||||
@@ -61,7 +61,7 @@ func (module *module) GetViewsForFilters(ctx context.Context, orgID string, sour
|
||||
func (module *module) CreateView(ctx context.Context, orgID string, view v3.SavedView) (valuer.UUID, error) {
|
||||
data, err := json.Marshal(view.CompositeQuery)
|
||||
if err != nil {
|
||||
return valuer.UUID{}, fmt.Errorf("error in marshalling explorer query data: %s", err.Error())
|
||||
return valuer.UUID{}, errors.WrapInternalf(err, errors.CodeInternal, "error in marshalling explorer query data")
|
||||
}
|
||||
|
||||
uuid := valuer.GenerateUUID()
|
||||
@@ -70,7 +70,7 @@ func (module *module) CreateView(ctx context.Context, orgID string, view v3.Save
|
||||
|
||||
claims, errv2 := authtypes.ClaimsFromContext(ctx)
|
||||
if errv2 != nil {
|
||||
return valuer.UUID{}, fmt.Errorf("error in getting email from context")
|
||||
return valuer.UUID{}, errors.NewInternalf(errors.CodeInternal, "error in getting email from context")
|
||||
}
|
||||
|
||||
createBy := claims.Email
|
||||
@@ -99,7 +99,7 @@ func (module *module) CreateView(ctx context.Context, orgID string, view v3.Save
|
||||
|
||||
_, err = module.sqlstore.BunDB().NewInsert().Model(&dbView).Exec(ctx)
|
||||
if err != nil {
|
||||
return valuer.UUID{}, fmt.Errorf("error in creating saved view: %s", err.Error())
|
||||
return valuer.UUID{}, errors.WrapInternalf(err, errors.CodeInternal, "error in creating saved view")
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
@@ -108,13 +108,13 @@ func (module *module) GetView(ctx context.Context, orgID string, uuid valuer.UUI
|
||||
var view types.SavedView
|
||||
err := module.sqlstore.BunDB().NewSelect().Model(&view).Where("org_id = ? AND id = ?", orgID, uuid.StringValue()).Scan(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in getting saved view: %s", err.Error())
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "error in getting saved view")
|
||||
}
|
||||
|
||||
var compositeQuery v3.CompositeQuery
|
||||
err = json.Unmarshal([]byte(view.Data), &compositeQuery)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error in unmarshalling explorer query data: %s", err.Error())
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "error in unmarshalling explorer query data")
|
||||
}
|
||||
return &v3.SavedView{
|
||||
ID: view.ID,
|
||||
@@ -134,12 +134,12 @@ func (module *module) GetView(ctx context.Context, orgID string, uuid valuer.UUI
|
||||
func (module *module) UpdateView(ctx context.Context, orgID string, uuid valuer.UUID, view v3.SavedView) error {
|
||||
data, err := json.Marshal(view.CompositeQuery)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in marshalling explorer query data: %s", err.Error())
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "error in marshalling explorer query data")
|
||||
}
|
||||
|
||||
claims, errv2 := authtypes.ClaimsFromContext(ctx)
|
||||
if errv2 != nil {
|
||||
return fmt.Errorf("error in getting email from context")
|
||||
return errors.NewInternalf(errors.CodeInternal, "error in getting email from context")
|
||||
}
|
||||
|
||||
updatedAt := time.Now()
|
||||
@@ -153,7 +153,7 @@ func (module *module) UpdateView(ctx context.Context, orgID string, uuid valuer.
|
||||
Where("org_id = ?", orgID).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in updating saved view: %s", err.Error())
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "error in updating saved view")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -165,7 +165,7 @@ func (module *module) DeleteView(ctx context.Context, orgID string, uuid valuer.
|
||||
Where("org_id = ?", orgID).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in deleting explorer query: %s", err.Error())
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "error in deleting explorer query")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ func TestBuildFunnelOverviewQuery_WithLatencyPointer(t *testing.T) {
|
||||
LatencyPointer string
|
||||
Clause string
|
||||
}
|
||||
startTs int64
|
||||
endTs int64
|
||||
wantContains []string
|
||||
startTs int64
|
||||
endTs int64
|
||||
wantContains []string
|
||||
wantNotContains []string
|
||||
}{
|
||||
{
|
||||
@@ -86,13 +86,13 @@ func TestBuildFunnelOverviewQuery_WithLatencyPointer(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
query := BuildFunnelOverviewQuery(tt.steps, tt.startTs, tt.endTs)
|
||||
|
||||
|
||||
for _, want := range tt.wantContains {
|
||||
if !strings.Contains(query, want) {
|
||||
t.Errorf("Query missing expected content: %s", want)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for _, notWant := range tt.wantNotContains {
|
||||
if strings.Contains(query, notWant) {
|
||||
t.Errorf("Query contains unexpected content: %s", notWant)
|
||||
@@ -142,7 +142,7 @@ func TestBuildFunnelStepOverviewQuery_WithLatencyPointer(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
query := BuildFunnelStepOverviewQuery(tt.steps, 1000000000, 2000000000, tt.stepStart, tt.stepEnd)
|
||||
|
||||
|
||||
for _, want := range tt.wantContains {
|
||||
if !strings.Contains(query, want) {
|
||||
t.Errorf("Query missing expected content: %s", want)
|
||||
@@ -154,10 +154,10 @@ func TestBuildFunnelStepOverviewQuery_WithLatencyPointer(t *testing.T) {
|
||||
|
||||
func TestBuildFunnelTopSlowTracesQuery_WithLatencyPointer(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
latencyPointerT1 string
|
||||
latencyPointerT2 string
|
||||
wantContains []string
|
||||
name string
|
||||
latencyPointerT1 string
|
||||
latencyPointerT2 string
|
||||
wantContains []string
|
||||
}{
|
||||
{
|
||||
name: "both steps with end latency",
|
||||
@@ -199,7 +199,7 @@ func TestBuildFunnelTopSlowTracesQuery_WithLatencyPointer(t *testing.T) {
|
||||
tt.latencyPointerT1,
|
||||
tt.latencyPointerT2,
|
||||
)
|
||||
|
||||
|
||||
for _, want := range tt.wantContains {
|
||||
if !strings.Contains(query, want) {
|
||||
t.Errorf("Query missing expected content: %s", want)
|
||||
@@ -211,10 +211,10 @@ func TestBuildFunnelTopSlowTracesQuery_WithLatencyPointer(t *testing.T) {
|
||||
|
||||
func TestBuildFunnelTopSlowErrorTracesQuery_WithLatencyPointer(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
latencyPointerT1 string
|
||||
latencyPointerT2 string
|
||||
wantContains []string
|
||||
name string
|
||||
latencyPointerT1 string
|
||||
latencyPointerT2 string
|
||||
wantContains []string
|
||||
}{
|
||||
{
|
||||
name: "both steps with end latency",
|
||||
@@ -247,7 +247,7 @@ func TestBuildFunnelTopSlowErrorTracesQuery_WithLatencyPointer(t *testing.T) {
|
||||
tt.latencyPointerT1,
|
||||
tt.latencyPointerT2,
|
||||
)
|
||||
|
||||
|
||||
for _, want := range tt.wantContains {
|
||||
if !strings.Contains(query, want) {
|
||||
t.Errorf("Query missing expected content: %s", want)
|
||||
@@ -255,4 +255,4 @@ func TestBuildFunnelTopSlowErrorTracesQuery_WithLatencyPointer(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
func TestBuildFunnelValidationQuery(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
steps []struct {
|
||||
name string
|
||||
steps []struct {
|
||||
ServiceName string
|
||||
SpanName string
|
||||
ContainsError int
|
||||
@@ -90,7 +90,7 @@ func TestBuildFunnelValidationQuery(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := BuildFunnelValidationQuery(tt.steps, tt.startTs, tt.endTs)
|
||||
|
||||
|
||||
for _, want := range tt.wantContains {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf("BuildFunnelValidationQuery() missing expected string: %q", want)
|
||||
@@ -103,8 +103,8 @@ func TestBuildFunnelValidationQuery(t *testing.T) {
|
||||
|
||||
func TestBuildFunnelOverviewQuery(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
steps []struct {
|
||||
name string
|
||||
steps []struct {
|
||||
ServiceName string
|
||||
SpanName string
|
||||
ContainsError int
|
||||
@@ -168,7 +168,7 @@ func TestBuildFunnelOverviewQuery(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := BuildFunnelOverviewQuery(tt.steps, tt.startTs, tt.endTs)
|
||||
|
||||
|
||||
for _, want := range tt.wantContains {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf("BuildFunnelOverviewQuery() missing expected string: %q", want)
|
||||
@@ -181,8 +181,8 @@ func TestBuildFunnelOverviewQuery(t *testing.T) {
|
||||
|
||||
func TestBuildFunnelCountQuery(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
steps []struct {
|
||||
name string
|
||||
steps []struct {
|
||||
ServiceName string
|
||||
SpanName string
|
||||
ContainsError int
|
||||
@@ -241,7 +241,7 @@ func TestBuildFunnelCountQuery(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := BuildFunnelCountQuery(tt.steps, tt.startTs, tt.endTs)
|
||||
|
||||
|
||||
for _, want := range tt.wantContains {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf("BuildFunnelCountQuery() missing expected string: %q", want)
|
||||
@@ -254,8 +254,8 @@ func TestBuildFunnelCountQuery(t *testing.T) {
|
||||
|
||||
func TestBuildFunnelStepOverviewQuery(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
steps []struct {
|
||||
name string
|
||||
steps []struct {
|
||||
ServiceName string
|
||||
SpanName string
|
||||
ContainsError int
|
||||
@@ -347,14 +347,14 @@ func TestBuildFunnelStepOverviewQuery(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := BuildFunnelStepOverviewQuery(tt.steps, tt.startTs, tt.endTs, tt.stepStart, tt.stepEnd)
|
||||
|
||||
|
||||
for _, want := range tt.wantContains {
|
||||
if !strings.Contains(got, want) {
|
||||
t.Errorf("BuildFunnelStepOverviewQuery() missing expected string: %q", want)
|
||||
t.Logf("Got query:\n%s", got)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if tt.wantFallback && !strings.Contains(got, "SELECT 0 AS conversion_rate") {
|
||||
t.Errorf("BuildFunnelStepOverviewQuery() expected fallback query for invalid step range")
|
||||
}
|
||||
@@ -376,17 +376,17 @@ func TestTemporalOrderingLogic(t *testing.T) {
|
||||
{ServiceName: "s3", SpanName: "sp3", ContainsError: 0, LatencyPointer: "start", Clause: ""},
|
||||
{ServiceName: "s4", SpanName: "sp4", ContainsError: 0, LatencyPointer: "start", Clause: ""},
|
||||
}, 1000000000, 2000000000)
|
||||
|
||||
|
||||
// Check that each step has proper temporal ordering (cumulative format)
|
||||
temporalChecks := []string{
|
||||
"t2_time > t1_time",
|
||||
"t2_time > t1_time AND t3_time > t2_time",
|
||||
"t2_time > t1_time AND t3_time > t2_time AND t4_time > t3_time",
|
||||
}
|
||||
|
||||
|
||||
for _, check := range temporalChecks {
|
||||
if !strings.Contains(query, check) {
|
||||
t.Errorf("Missing temporal ordering check: %s", check)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package impltracefunnel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/modules/tracefunnel"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
traceFunnels "github.com/SigNoz/signoz/pkg/types/tracefunneltypes"
|
||||
@@ -76,7 +76,7 @@ func (module *module) Update(ctx context.Context, funnel *traceFunnels.StorableF
|
||||
func (module *module) List(ctx context.Context, orgID valuer.UUID) ([]*traceFunnels.StorableFunnel, error) {
|
||||
funnels, err := module.store.List(ctx, orgID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list funnels: %v", err)
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to list funnels")
|
||||
}
|
||||
|
||||
return funnels, nil
|
||||
|
||||
@@ -110,12 +110,12 @@ func (store *store) Update(ctx context.Context, funnel *traceFunnels.StorableFun
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to update funnel")
|
||||
}
|
||||
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, errors.TypeInternal, errors.CodeInternal, "failed to commit transaction")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ func TestModule_Update_DuplicateNameValidation(t *testing.T) {
|
||||
userID := valuer.GenerateUUID()
|
||||
orgID := valuer.GenerateUUID()
|
||||
funnelName := "Duplicate Name"
|
||||
|
||||
|
||||
funnel := &traceFunnels.StorableFunnel{
|
||||
Name: funnelName,
|
||||
OrgID: orgID,
|
||||
@@ -93,4 +93,4 @@ func (m *MockStore) Update(ctx context.Context, funnel *traceFunnels.StorableFun
|
||||
func (m *MockStore) Delete(ctx context.Context, uuid valuer.UUID, orgID valuer.UUID) error {
|
||||
args := m.Called(ctx, uuid, orgID)
|
||||
return args.Error(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package tracefunnel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
tracev4 "github.com/SigNoz/signoz/pkg/query-service/app/traces/v4"
|
||||
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
||||
"github.com/SigNoz/signoz/pkg/types/tracefunneltypes"
|
||||
@@ -113,7 +113,7 @@ func GetFunnelAnalytics(funnel *tracefunneltypes.StorableFunnel, timeRange trace
|
||||
|
||||
func GetFunnelStepAnalytics(funnel *tracefunneltypes.StorableFunnel, timeRange tracefunneltypes.TimeRange, stepStart, stepEnd int64) (*v3.ClickHouseQuery, error) {
|
||||
if stepStart == stepEnd {
|
||||
return nil, fmt.Errorf("step start and end cannot be the same for /step/overview")
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "step start and end cannot be the same for /step/overview")
|
||||
}
|
||||
|
||||
funnelSteps := funnel.Steps
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestValidateTracesMultipleSteps(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := ValidateTraces(tt.funnel, tt.timeRange)
|
||||
|
||||
|
||||
if tt.expectError && err == nil {
|
||||
t.Errorf("ValidateTraces() expected error but got none")
|
||||
}
|
||||
@@ -150,7 +150,7 @@ func TestGetFunnelAnalyticsMultipleSteps(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := GetFunnelAnalytics(tt.funnel, tt.timeRange)
|
||||
|
||||
|
||||
if tt.expectError && err == nil {
|
||||
t.Errorf("GetFunnelAnalytics() expected error but got none")
|
||||
}
|
||||
@@ -177,14 +177,14 @@ func TestGetStepAnalyticsMultipleSteps(t *testing.T) {
|
||||
{ServiceName: "s5", SpanName: "sp5", HasErrors: true, Filters: &v3.FilterSet{}},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
timeRange := tracefunneltypes.TimeRange{
|
||||
StartTime: 1000000000,
|
||||
EndTime: 2000000000,
|
||||
}
|
||||
|
||||
result, err := GetStepAnalytics(funnel, timeRange)
|
||||
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("GetStepAnalytics() unexpected error: %v", err)
|
||||
}
|
||||
@@ -246,7 +246,7 @@ func TestGetFunnelStepAnalyticsMultipleSteps(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := GetFunnelStepAnalytics(tt.funnel, tt.timeRange, tt.stepStart, tt.stepEnd)
|
||||
|
||||
|
||||
if tt.expectError && err == nil {
|
||||
t.Errorf("GetFunnelStepAnalytics() expected error but got none")
|
||||
}
|
||||
@@ -268,4 +268,4 @@ func init() {
|
||||
// This would normally be handled by the actual implementation
|
||||
// For testing purposes, we'll assume it returns an empty string
|
||||
_ = tracev4.BuildTracesFilterQuery
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,13 @@ package clickhouseprometheus
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/constants"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/constants"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrystore"
|
||||
promValue "github.com/prometheus/prometheus/model/value"
|
||||
"github.com/prometheus/prometheus/prompb"
|
||||
@@ -122,7 +123,7 @@ func (client *client) queryToClickhouseQuery(_ context.Context, query *prompb.Qu
|
||||
case prompb.LabelMatcher_NRE:
|
||||
conditions = append(conditions, fmt.Sprintf("not match(JSONExtractString(labels, $%d), $%d)", argCount+2, argCount+3))
|
||||
default:
|
||||
return "", nil, fmt.Errorf("unexpected matcher found in query: %s", m.Type.String())
|
||||
return "", nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "unsupported or invalid matcher type: %s", m.Type.String())
|
||||
}
|
||||
args = append(args, m.Name, m.Value)
|
||||
argCount += 2
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package prometheus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
)
|
||||
|
||||
@@ -43,7 +43,7 @@ func RemoveExtraLabels(res *promql.Result, labelsToRemove ...string) error {
|
||||
case promql.Scalar:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("rule result is not a vector or scalar or matrix")
|
||||
return errors.NewInternalf(errors.CodeInternal, "rule result is not a vector or scalar or matrix")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -237,7 +237,6 @@ func postProcessTraceOperator(
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
// applyMetricReduceTo applies reduce to operation using the metric's ReduceTo field
|
||||
func (q *querier) applyMetricReduceTo(result *qbtypes.Result, reduceOp qbtypes.ReduceTo) *qbtypes.Result {
|
||||
tsData, ok := result.Value.(*qbtypes.TimeSeriesData)
|
||||
|
||||
@@ -140,7 +140,7 @@ func (q *querier) QueryRange(ctx context.Context, orgID valuer.UUID, req *qbtype
|
||||
if spec, ok := query.Spec.(qbtypes.QueryBuilderTraceOperator); ok {
|
||||
// Parse expression to find dependencies
|
||||
if err := spec.ParseExpression(); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse trace operator expression: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deps := spec.CollectReferencedQueries(spec.ParsedExpression)
|
||||
@@ -652,7 +652,7 @@ func (q *querier) executeWithCache(ctx context.Context, orgID valuer.UUID, query
|
||||
|
||||
// Execute queries for missing ranges with bounded parallelism
|
||||
freshResults := make([]*qbtypes.Result, len(missingRanges))
|
||||
errors := make([]error, len(missingRanges))
|
||||
errs := make([]error, len(missingRanges))
|
||||
totalStats := qbtypes.ExecStats{}
|
||||
|
||||
q.logger.DebugContext(ctx, "executing queries for missing ranges",
|
||||
@@ -673,14 +673,14 @@ func (q *querier) executeWithCache(ctx context.Context, orgID valuer.UUID, query
|
||||
// Create a new query with the missing time range
|
||||
rangedQuery := q.createRangedQuery(query, *tr)
|
||||
if rangedQuery == nil {
|
||||
errors[idx] = fmt.Errorf("failed to create ranged query for range %d-%d", tr.From, tr.To)
|
||||
errs[idx] = errors.NewInternalf(errors.CodeInternal, "failed to create ranged query for range %d-%d", tr.From, tr.To)
|
||||
return
|
||||
}
|
||||
|
||||
// Execute the ranged query
|
||||
result, err := rangedQuery.Execute(ctx)
|
||||
if err != nil {
|
||||
errors[idx] = err
|
||||
errs[idx] = err
|
||||
return
|
||||
}
|
||||
|
||||
@@ -692,7 +692,7 @@ func (q *querier) executeWithCache(ctx context.Context, orgID valuer.UUID, query
|
||||
wg.Wait()
|
||||
|
||||
// Check for errors
|
||||
for _, err := range errors {
|
||||
for _, err := range errs {
|
||||
if err != nil {
|
||||
// If any query failed, fall back to full execution
|
||||
q.logger.ErrorContext(ctx, "parallel query execution failed", "error", err)
|
||||
|
||||
@@ -87,4 +87,3 @@ func (q *traceOperatorQuery) executeWithContext(ctx context.Context, query strin
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
grammar "github.com/SigNoz/signoz/pkg/parser/grammar"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/antlr4-go/antlr/v4"
|
||||
@@ -54,7 +55,7 @@ func DetectContradictions(query string) ([]string, error) {
|
||||
|
||||
// Check for syntax errors
|
||||
if len(parserErrorListener.SyntaxErrors) > 0 {
|
||||
return nil, fmt.Errorf("syntax errors: %v", parserErrorListener.SyntaxErrors)
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "syntax errors: %v", parserErrorListener.SyntaxErrors)
|
||||
}
|
||||
|
||||
// Create detector and visit tree
|
||||
@@ -856,7 +857,7 @@ func parseNumericValue(value interface{}) (float64, error) {
|
||||
case string:
|
||||
return strconv.ParseFloat(v, 64)
|
||||
default:
|
||||
return 0, fmt.Errorf("not a numeric value")
|
||||
return 0, errors.NewInvalidInputf(errors.CodeInvalidInput, "not a numeric value")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ func (b *resourceFilterStatementBuilder[T]) Build(
|
||||
) (*qbtypes.Statement, error) {
|
||||
config, exists := signalConfigs[b.signal]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("%w: %s", ErrUnsupportedSignal, b.signal)
|
||||
return nil, errors.WrapInvalidInputf(ErrUnsupportedSignal, errors.CodeInvalidInput, "unsupported signal: %s", b.signal)
|
||||
}
|
||||
|
||||
q := sqlbuilder.NewSelectBuilder()
|
||||
|
||||
@@ -2,7 +2,6 @@ package signoz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -16,6 +15,7 @@ import (
|
||||
"github.com/SigNoz/signoz/pkg/cache"
|
||||
"github.com/SigNoz/signoz/pkg/config"
|
||||
"github.com/SigNoz/signoz/pkg/emailing"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/gateway"
|
||||
"github.com/SigNoz/signoz/pkg/instrumentation"
|
||||
@@ -182,11 +182,11 @@ func validateConfig(config Config) error {
|
||||
for i := 0; i < rvConfig.NumField(); i++ {
|
||||
factoryConfig, ok := rvConfig.Field(i).Interface().(factory.Config)
|
||||
if !ok {
|
||||
return fmt.Errorf("%q is not of type \"factory.Config\"", rvConfig.Type().Field(i).Name)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "%q is not of type \"factory.Config\"", rvConfig.Type().Field(i).Name)
|
||||
}
|
||||
|
||||
if err := factoryConfig.Validate(); err != nil {
|
||||
return fmt.Errorf("failed to validate config %q: %w", rvConfig.Type().Field(i).Tag.Get("mapstructure"), err)
|
||||
return errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "failed to validate config %q", rvConfig.Type().Field(i).Tag.Get("mapstructure"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ func (c *Client) Do(ctx context.Context, tos []*mail.Address, subject string, co
|
||||
if c.hello != "" {
|
||||
err = smtpClient.Hello(c.hello)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send EHLO command: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to send EHLO command")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ func (c *Client) Do(ctx context.Context, tos []*mail.Address, subject string, co
|
||||
if !c.tls.Enabled {
|
||||
if ok, _ := smtpClient.Extension("STARTTLS"); ok {
|
||||
if err := smtpClient.StartTLS(c.tlsConfig); err != nil {
|
||||
return fmt.Errorf("failed to send STARTTLS command: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to send STARTTLS command")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,32 +136,32 @@ func (c *Client) Do(ctx context.Context, tos []*mail.Address, subject string, co
|
||||
if c.auth.Username != "" {
|
||||
auth, err := c.smtpAuth(ctx, mech)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find auth mechanism: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to find auth mechanism")
|
||||
}
|
||||
|
||||
// Send the AUTH command.
|
||||
if err := smtpClient.Auth(auth); err != nil {
|
||||
return fmt.Errorf("failed to auth: %T: %w", auth, err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to auth: %T", auth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send the MAIL command.
|
||||
if err = smtpClient.Mail(c.from.Address); err != nil {
|
||||
return fmt.Errorf("failed to send MAIL command: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to send MAIL command")
|
||||
}
|
||||
|
||||
// Send the RCPT command for each recipient.
|
||||
for _, addr := range tos {
|
||||
if err = smtpClient.Rcpt(addr.Address); err != nil {
|
||||
return fmt.Errorf("failed to send RCPT command: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to send RCPT command")
|
||||
}
|
||||
}
|
||||
|
||||
// Send the email headers and body.
|
||||
message, err := smtpClient.Data()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send DATA command: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to send DATA command")
|
||||
}
|
||||
|
||||
closeOnce := sync.OnceValue(func() error {
|
||||
@@ -200,7 +200,7 @@ func (c *Client) Do(ctx context.Context, tos []*mail.Address, subject string, co
|
||||
|
||||
_, err = message.Write(buffer.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write headers: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to write headers")
|
||||
}
|
||||
|
||||
// Text template
|
||||
@@ -210,17 +210,17 @@ func (c *Client) Do(ctx context.Context, tos []*mail.Address, subject string, co
|
||||
"Content-Type": {"text/plain; charset=UTF-8"},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create part for text template: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to create part for text template")
|
||||
}
|
||||
|
||||
qw := quotedprintable.NewWriter(w)
|
||||
_, err = qw.Write([]byte(body))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write text part: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to write text part")
|
||||
}
|
||||
err = qw.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to close text part: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to close text part")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,33 +233,33 @@ func (c *Client) Do(ctx context.Context, tos []*mail.Address, subject string, co
|
||||
"Content-Type": {"text/html; charset=UTF-8"},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create part for html template: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to create part for html template")
|
||||
}
|
||||
|
||||
qw := quotedprintable.NewWriter(w)
|
||||
_, err = qw.Write([]byte(body))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write HTML part: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to write HTML part")
|
||||
}
|
||||
err = qw.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to close HTML part: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to close HTML part")
|
||||
}
|
||||
}
|
||||
|
||||
err = multipartWriter.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to close multipartWriter: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to close multipartWriter")
|
||||
}
|
||||
|
||||
_, err = message.Write(multipartBuffer.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write body buffer: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to write body buffer")
|
||||
}
|
||||
|
||||
// Complete the message and await response.
|
||||
if err = closeOnce(); err != nil {
|
||||
return fmt.Errorf("failed to deliver: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "failed to deliver")
|
||||
}
|
||||
|
||||
success = true
|
||||
@@ -317,7 +317,7 @@ func (c *Client) dial(ctx context.Context) (net.Conn, error) {
|
||||
if c.tls.Enabled || c.port == "465" {
|
||||
conn, err = tls.Dial("tcp", c.address, c.tlsConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to establish TLS connection to server: %w", err)
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to establish TLS connection to server")
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
@@ -326,7 +326,7 @@ func (c *Client) dial(ctx context.Context) (net.Conn, error) {
|
||||
var d net.Dialer
|
||||
conn, err = d.DialContext(ctx, "tcp", c.address)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to establish connection to server: %w", err)
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to establish connection to server")
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
@@ -341,7 +341,7 @@ func newTLSConfig(config TLS, serverName string) (*tls.Config, error) {
|
||||
if config.CertFilePath != "" {
|
||||
cert, err := tls.LoadX509KeyPair(config.CertFilePath, config.KeyFilePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load cert or key file: %w", err)
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to load cert or key file")
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
@@ -349,11 +349,11 @@ func newTLSConfig(config TLS, serverName string) (*tls.Config, error) {
|
||||
if config.CAFilePath != "" {
|
||||
ca, err := os.ReadFile(config.CAFilePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load CA file: %w", err)
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to load CA file")
|
||||
}
|
||||
tlsConfig.RootCAs = x509.NewCertPool()
|
||||
if !tlsConfig.RootCAs.AppendCertsFromPEM(ca) {
|
||||
return nil, fmt.Errorf("failed to append CA file: %s", config.CAFilePath)
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to append CA file: %s", config.CAFilePath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ func parseAllColumns(in string) ([]sqlschema.ColumnName, error) {
|
||||
quote = ']'
|
||||
continue
|
||||
} else if s[i] == ')' {
|
||||
return columns, fmt.Errorf("unexpected token: %s", string(s[i]))
|
||||
return columns, errors.NewInternalf(ErrCodeInvalidDDL, "unexpected token: %s", string(s[i]))
|
||||
}
|
||||
state = parseAllColumnsState_ReadingRawName
|
||||
name = append(name, s[i])
|
||||
@@ -267,7 +267,7 @@ func parseAllColumns(in string) ([]sqlschema.ColumnName, error) {
|
||||
columns = append(columns, sqlschema.ColumnName(name))
|
||||
}
|
||||
if isQuote(s[i]) {
|
||||
return nil, fmt.Errorf("unexpected token: %s", string(s[i]))
|
||||
return nil, errors.NewInternalf(ErrCodeInvalidDDL, "unexpected token: %s", string(s[i]))
|
||||
}
|
||||
if isSpace(s[i]) {
|
||||
state = parseAllColumnsState_EndOfName
|
||||
|
||||
@@ -3,7 +3,6 @@ package sqlstoretest
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
@@ -35,7 +34,7 @@ func New(config sqlstore.Config, matcher sqlmock.QueryMatcher) *Provider {
|
||||
} else if config.Provider == "postgres" {
|
||||
bunDB = bun.NewDB(db, pgdialect.New())
|
||||
} else {
|
||||
panic(fmt.Errorf("provider %q is not supported", config.Provider))
|
||||
panic(errors.NewInvalidInputf(errors.CodeInvalidInput, "provider %q is not supported", config.Provider))
|
||||
}
|
||||
|
||||
return &Provider{
|
||||
@@ -71,9 +70,9 @@ func (provider *Provider) RunInTxCtx(ctx context.Context, opts *sql.TxOptions, c
|
||||
}
|
||||
|
||||
func (provider *Provider) WrapNotFoundErrf(err error, code errors.Code, format string, args ...any) error {
|
||||
return fmt.Errorf(format, args...)
|
||||
return errors.WrapNotFoundf(err, code, format, args...)
|
||||
}
|
||||
|
||||
func (provider *Provider) WrapAlreadyExistsErrf(err error, code errors.Code, format string, args ...any) error {
|
||||
return fmt.Errorf(format, args...)
|
||||
return errors.Wrapf(err, errors.TypeAlreadyExists, code, format, args...)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
schema "github.com/SigNoz/signoz-otel-collector/cmd/signozschemamigrator/schema_migrator"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
@@ -205,10 +206,10 @@ func (c *conditionBuilder) conditionFor(
|
||||
return sb.NE(leftOperand, true), nil
|
||||
}
|
||||
default:
|
||||
return "", fmt.Errorf("exists operator is not supported for column type %s", column.Type)
|
||||
return "", errors.NewInvalidInputf(errors.CodeInvalidInput, "exists operator is not supported for column type %s", column.Type)
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("unsupported operator: %v", operator)
|
||||
return "", errors.NewInvalidInputf(errors.CodeInvalidInput, "unsupported operator: %v", operator)
|
||||
}
|
||||
|
||||
func (c *conditionBuilder) ConditionFor(
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
@@ -87,7 +88,7 @@ func (b *logQueryStatementBuilder) Build(
|
||||
return b.buildScalarQuery(ctx, q, query, start, end, keys, false, variables)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported request type: %s", requestType)
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "unsupported request type: %s", requestType)
|
||||
}
|
||||
|
||||
func getKeySelectors(query qbtypes.QueryBuilderQuery[qbtypes.LogAggregation]) []*telemetrytypes.FieldKeySelector {
|
||||
|
||||
@@ -2,10 +2,10 @@ package telemetrymetadata
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/instrumentation/instrumentationtest"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrylogs"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrymeter"
|
||||
@@ -28,7 +28,7 @@ func (m *regexMatcher) Match(expectedSQL, actualSQL string) error {
|
||||
return err
|
||||
}
|
||||
if !re.MatchString(actualSQL) {
|
||||
return fmt.Errorf("expected query to contain %s, got %s", expectedSQL, actualSQL)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "expected query to contain %s, got %s", expectedSQL, actualSQL)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ func (c *conditionBuilder) conditionFor(
|
||||
return sb.NE(leftOperand, true), nil
|
||||
}
|
||||
default:
|
||||
return "", fmt.Errorf("exists operator is not supported for column type %s", column.Type)
|
||||
return "", errors.NewInvalidInputf(errors.CodeInvalidInput, "exists operator is not supported for column type %s", column.Type)
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
|
||||
@@ -82,9 +82,9 @@ func (b *traceQueryStatementBuilder) Build(
|
||||
if found && len(traceIDs) > 0 {
|
||||
finder := NewTraceTimeRangeFinder(b.telemetryStore)
|
||||
|
||||
traceStart, traceEnd, err := finder.GetTraceTimeRangeMulti(ctx, traceIDs)
|
||||
if err != nil {
|
||||
b.logger.DebugContext(ctx, "failed to get trace time range", "trace_ids", traceIDs, "error", err)
|
||||
traceStart, traceEnd, ok := finder.GetTraceTimeRangeMulti(ctx, traceIDs)
|
||||
if !ok {
|
||||
b.logger.DebugContext(ctx, "failed to get trace time range", "trace_ids", traceIDs)
|
||||
} else if traceStart > 0 && traceEnd > 0 {
|
||||
start = uint64(traceStart)
|
||||
end = uint64(traceEnd)
|
||||
@@ -107,7 +107,7 @@ func (b *traceQueryStatementBuilder) Build(
|
||||
return b.buildTraceQuery(ctx, q, query, start, end, keys, variables)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported request type: %s", requestType)
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "unsupported request type: %s", requestType)
|
||||
}
|
||||
|
||||
func getKeySelectors(query qbtypes.QueryBuilderQuery[qbtypes.TraceAggregation]) []*telemetrytypes.FieldKeySelector {
|
||||
|
||||
@@ -3,12 +3,13 @@ package telemetrytraces
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/querybuilder"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
"github.com/huandu/go-sqlbuilder"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type cteNode struct {
|
||||
@@ -402,7 +403,7 @@ func (b *traceOperatorCTEBuilder) buildFinalQuery(ctx context.Context, selectFro
|
||||
case qbtypes.RequestTypeScalar:
|
||||
return b.buildScalarQuery(ctx, selectFromCTE)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported request type: %s", requestType)
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "unsupported request type: %s", requestType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package telemetrytraces
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -19,14 +18,14 @@ func NewTraceTimeRangeFinder(telemetryStore telemetrystore.TelemetryStore) *Trac
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TraceTimeRangeFinder) GetTraceTimeRange(ctx context.Context, traceID string) (startNano, endNano int64, err error) {
|
||||
func (f *TraceTimeRangeFinder) GetTraceTimeRange(ctx context.Context, traceID string) (startNano, endNano int64, ok bool) {
|
||||
traceIDs := []string{traceID}
|
||||
return f.GetTraceTimeRangeMulti(ctx, traceIDs)
|
||||
}
|
||||
|
||||
func (f *TraceTimeRangeFinder) GetTraceTimeRangeMulti(ctx context.Context, traceIDs []string) (startNano, endNano int64, err error) {
|
||||
func (f *TraceTimeRangeFinder) GetTraceTimeRangeMulti(ctx context.Context, traceIDs []string) (startNano, endNano int64, ok bool) {
|
||||
if len(traceIDs) == 0 {
|
||||
return 0, 0, fmt.Errorf("no trace IDs provided")
|
||||
return 0, 0, false
|
||||
}
|
||||
|
||||
cleanedIDs := make([]string, len(traceIDs))
|
||||
@@ -51,12 +50,9 @@ func (f *TraceTimeRangeFinder) GetTraceTimeRangeMulti(ctx context.Context, trace
|
||||
|
||||
row := f.telemetryStore.ClickhouseDB().QueryRow(ctx, query, args...)
|
||||
|
||||
err = row.Scan(&startNano, &endNano)
|
||||
err := row.Scan(&startNano, &endNano)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return 0, 0, fmt.Errorf("traces not found: %v", cleanedIDs)
|
||||
}
|
||||
return 0, 0, fmt.Errorf("failed to query trace time range: %w", err)
|
||||
return 0, 0, false
|
||||
}
|
||||
|
||||
if startNano > 1_000_000_000 {
|
||||
@@ -64,5 +60,5 @@ func (f *TraceTimeRangeFinder) GetTraceTimeRangeMulti(ctx context.Context, trace
|
||||
}
|
||||
endNano += 1_000_000_000
|
||||
|
||||
return startNano, endNano, nil
|
||||
return startNano, endNano, true
|
||||
}
|
||||
|
||||
@@ -12,29 +12,29 @@ func TestGetTraceTimeRangeMulti(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
traceIDs []string
|
||||
expectErr bool
|
||||
name string
|
||||
traceIDs []string
|
||||
expectOK bool
|
||||
}{
|
||||
{
|
||||
name: "single trace ID",
|
||||
traceIDs: []string{"trace1"},
|
||||
expectErr: false,
|
||||
name: "single trace ID",
|
||||
traceIDs: []string{"trace1"},
|
||||
expectOK: true,
|
||||
},
|
||||
{
|
||||
name: "multiple trace IDs",
|
||||
traceIDs: []string{"trace1", "trace2", "trace3"},
|
||||
expectErr: false,
|
||||
name: "multiple trace IDs",
|
||||
traceIDs: []string{"trace1", "trace2", "trace3"},
|
||||
expectOK: true,
|
||||
},
|
||||
{
|
||||
name: "empty trace IDs",
|
||||
traceIDs: []string{},
|
||||
expectErr: true,
|
||||
name: "empty trace IDs",
|
||||
traceIDs: []string{},
|
||||
expectOK: false,
|
||||
},
|
||||
{
|
||||
name: "trace IDs with quotes",
|
||||
traceIDs: []string{"'trace1'", `"trace2"`, "trace3"},
|
||||
expectErr: false,
|
||||
name: "trace IDs with quotes",
|
||||
traceIDs: []string{"'trace1'", `"trace2"`, "trace3"},
|
||||
expectOK: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@ func TestGetTraceTimeRangeMulti(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
finder := &TraceTimeRangeFinder{telemetryStore: nil}
|
||||
|
||||
if tt.expectErr {
|
||||
_, _, err := finder.GetTraceTimeRangeMulti(ctx, tt.traceIDs)
|
||||
assert.Error(t, err)
|
||||
if !tt.expectOK {
|
||||
_, _, ok := finder.GetTraceTimeRangeMulti(ctx, tt.traceIDs)
|
||||
assert.False(t, ok)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package alertmanagertypes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
alertmanagertemplate "github.com/prometheus/alertmanager/template"
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ func FromGlobs(paths []string) (*alertmanagertemplate.Template, error) {
|
||||
{{ define "__alertmanagerURL" }}{{ .ExternalURL }}/alerts{{ template "__ruleIdPath" . }}{{ end }}
|
||||
{{ define "msteamsv2.default.titleLink" }}{{ template "__alertmanagerURL" . }}{{ end }}
|
||||
`))); err != nil {
|
||||
return nil, fmt.Errorf("error parsing alertmanager templates: %w", err)
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "error parsing alertmanager templates")
|
||||
}
|
||||
|
||||
return t, nil
|
||||
|
||||
@@ -3,10 +3,9 @@ package types
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
@@ -45,7 +44,7 @@ func (c *InstalledIntegrationConfig) Scan(src interface{}) error {
|
||||
case string:
|
||||
data = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("tried to scan from %T instead of string or bytes", src)
|
||||
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, c)
|
||||
@@ -55,7 +54,7 @@ func (c *InstalledIntegrationConfig) Scan(src interface{}) error {
|
||||
func (c *InstalledIntegrationConfig) Value() (driver.Value, error) {
|
||||
filterSetJson, err := json.Marshal(c)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not serialize integration config to JSON")
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "could not serialize integration config to JSON")
|
||||
}
|
||||
return filterSetJson, nil
|
||||
}
|
||||
@@ -136,7 +135,7 @@ func (c *AccountConfig) Scan(src any) error {
|
||||
case string:
|
||||
data = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("tried to scan from %T instead of string or bytes", src)
|
||||
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, c)
|
||||
@@ -145,12 +144,12 @@ func (c *AccountConfig) Scan(src any) error {
|
||||
// For serializing to db
|
||||
func (c *AccountConfig) Value() (driver.Value, error) {
|
||||
if c == nil {
|
||||
return nil, fmt.Errorf("cloud account config is nil")
|
||||
return nil, errors.NewInternalf(errors.CodeInternal, "cloud account config is nil")
|
||||
}
|
||||
|
||||
serialized, err := json.Marshal(c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't serialize cloud account config to JSON: %w", err)
|
||||
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't serialize cloud account config to JSON")
|
||||
}
|
||||
return serialized, nil
|
||||
}
|
||||
@@ -169,7 +168,7 @@ func (r *AgentReport) Scan(src any) error {
|
||||
case string:
|
||||
data = []byte(v)
|
||||
default:
|
||||
return fmt.Errorf("tried to scan from %T instead of string or bytes", src)
|
||||
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, r)
|
||||
@@ -178,13 +177,13 @@ func (r *AgentReport) Scan(src any) error {
|
||||
// For serializing to db
|
||||
func (r *AgentReport) Value() (driver.Value, error) {
|
||||
if r == nil {
|
||||
return nil, fmt.Errorf("agent report is nil")
|
||||
return nil, errors.NewInternalf(errors.CodeInternal, "agent report is nil")
|
||||
}
|
||||
|
||||
serialized, err := json.Marshal(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"couldn't serialize agent report to JSON: %w", err,
|
||||
return nil, errors.WrapInternalf(
|
||||
err, errors.CodeInternal, "couldn't serialize agent report to JSON",
|
||||
)
|
||||
}
|
||||
return serialized, nil
|
||||
@@ -223,7 +222,7 @@ func (c *CloudServiceConfig) Scan(src any) error {
|
||||
case string:
|
||||
data = []byte(src)
|
||||
default:
|
||||
return fmt.Errorf("tried to scan from %T instead of string or bytes", src)
|
||||
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, c)
|
||||
@@ -232,13 +231,13 @@ func (c *CloudServiceConfig) Scan(src any) error {
|
||||
// For serializing to db
|
||||
func (c *CloudServiceConfig) Value() (driver.Value, error) {
|
||||
if c == nil {
|
||||
return nil, fmt.Errorf("cloud service config is nil")
|
||||
return nil, errors.NewInternalf(errors.CodeInternal, "cloud service config is nil")
|
||||
}
|
||||
|
||||
serialized, err := json.Marshal(c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"couldn't serialize cloud service config to JSON: %w", err,
|
||||
return nil, errors.WrapInternalf(
|
||||
err, errors.CodeInternal, "couldn't serialize cloud service config to JSON",
|
||||
)
|
||||
}
|
||||
return serialized, nil
|
||||
|
||||
@@ -3,7 +3,6 @@ package licensetypes
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
@@ -113,9 +112,9 @@ func extractKeyFromMapStringInterface[T any](data map[string]interface{}, key st
|
||||
if value, ok := val.(T); ok {
|
||||
return value, nil
|
||||
}
|
||||
return zeroValue, fmt.Errorf("%s key is not a valid %s", key, reflect.TypeOf(zeroValue))
|
||||
return zeroValue, errors.NewInvalidInputf(errors.CodeInvalidInput, "%s key is not a valid %s", key, reflect.TypeOf(zeroValue))
|
||||
}
|
||||
return zeroValue, fmt.Errorf("%s key is missing", key)
|
||||
return zeroValue, errors.NewInvalidInputf(errors.CodeInvalidInput, "%s key is missing", key)
|
||||
}
|
||||
|
||||
func NewLicense(data []byte, organizationID valuer.UUID) (*License, error) {
|
||||
|
||||
@@ -2,15 +2,14 @@ package pipelinetypes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3"
|
||||
"github.com/SigNoz/signoz/pkg/query-service/queryBuilderToExpr"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
@@ -66,7 +65,7 @@ func (i *GettablePipeline) ParseRawConfig() error {
|
||||
c := []PipelineOperator{}
|
||||
err := json.Unmarshal([]byte(i.ConfigJSON), &c)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse ingestion rule config")
|
||||
return errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "failed to parse ingestion rule config")
|
||||
}
|
||||
i.Config = c
|
||||
return nil
|
||||
@@ -76,7 +75,7 @@ func (i *GettablePipeline) ParseFilter() error {
|
||||
f := v3.FilterSet{}
|
||||
err := json.Unmarshal([]byte(i.FilterString), &f)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse filter")
|
||||
return errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "failed to parse filter")
|
||||
}
|
||||
i.Filter = &f
|
||||
return nil
|
||||
@@ -208,20 +207,20 @@ type PostablePipeline struct {
|
||||
// IsValid checks if postable pipeline has all the required params
|
||||
func (p *PostablePipeline) IsValid() error {
|
||||
if p.OrderID == 0 {
|
||||
return fmt.Errorf("orderId with value > 1 is required")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "orderId with value > 1 is required")
|
||||
}
|
||||
if p.Name == "" {
|
||||
return fmt.Errorf("pipeline name is required")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "pipeline name is required")
|
||||
}
|
||||
|
||||
if p.Alias == "" {
|
||||
return fmt.Errorf("pipeline alias is required")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "pipeline alias is required")
|
||||
}
|
||||
|
||||
// check the filter
|
||||
_, err := queryBuilderToExpr.Parse(p.Filter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("filter for pipeline %v is not correct: %v", p.Name, err.Error())
|
||||
return errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "filter for pipeline %v is not correct", p.Name)
|
||||
}
|
||||
|
||||
idUnique := map[string]struct{}{}
|
||||
@@ -230,30 +229,30 @@ func (p *PostablePipeline) IsValid() error {
|
||||
l := len(p.Config)
|
||||
for i, op := range p.Config {
|
||||
if op.OrderId == 0 {
|
||||
return fmt.Errorf("orderId with value > 1 is required in operator")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "orderId with value > 1 is required in operator")
|
||||
}
|
||||
if op.ID == "" {
|
||||
return fmt.Errorf("id of an operator cannot be empty")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "id of an operator cannot be empty")
|
||||
}
|
||||
if op.Type == "" {
|
||||
return fmt.Errorf("type of an operator cannot be empty")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "type of an operator cannot be empty")
|
||||
}
|
||||
if i != (l-1) && op.Output == "" {
|
||||
return fmt.Errorf("output of operator %s cannot be nil", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "output of operator %s cannot be nil", op.ID)
|
||||
}
|
||||
if i == (l-1) && op.Output != "" {
|
||||
return fmt.Errorf("output of operator %s should be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "output of operator %s should be empty", op.ID)
|
||||
}
|
||||
|
||||
if _, ok := idUnique[op.ID]; ok {
|
||||
return fmt.Errorf("duplicate id cannot be present")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "duplicate id cannot be present")
|
||||
}
|
||||
if _, ok := outputUnique[op.Output]; ok {
|
||||
return fmt.Errorf("duplicate output cannot be present")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "duplicate output cannot be present")
|
||||
}
|
||||
|
||||
if op.ID == op.Output {
|
||||
return fmt.Errorf("id and output cannot be same")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "id and output cannot be same")
|
||||
}
|
||||
|
||||
err := isValidOperator(op)
|
||||
@@ -269,31 +268,31 @@ func (p *PostablePipeline) IsValid() error {
|
||||
|
||||
func isValidOperator(op PipelineOperator) error {
|
||||
if op.ID == "" {
|
||||
return errors.New("PipelineOperator.ID is required")
|
||||
return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "PipelineOperator.ID is required")
|
||||
}
|
||||
|
||||
switch op.Type {
|
||||
case "json_parser":
|
||||
if op.ParseFrom == "" && op.ParseTo == "" {
|
||||
return fmt.Errorf("parse from and parse to of %s json operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "parse from and parse to of %s json operator cannot be empty", op.ID)
|
||||
}
|
||||
|
||||
for k := range op.Mapping {
|
||||
if !slices.Contains(validMappingVariableTypes, strings.ToLower(k)) {
|
||||
return fmt.Errorf("%s is not a valid mapping type in processor %s", k, op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "%s is not a valid mapping type in processor %s", k, op.ID)
|
||||
}
|
||||
}
|
||||
case "grok_parser":
|
||||
if op.Pattern == "" {
|
||||
return fmt.Errorf("pattern of %s grok operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "pattern of %s grok operator cannot be empty", op.ID)
|
||||
}
|
||||
case "regex_parser":
|
||||
if op.Regex == "" {
|
||||
return fmt.Errorf("regex of %s regex operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "regex of %s regex operator cannot be empty", op.ID)
|
||||
}
|
||||
r, err := regexp.Compile(op.Regex)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error compiling regex expression of %s regex operator", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "error compiling regex expression of %s regex operator", op.ID)
|
||||
}
|
||||
namedCaptureGroups := 0
|
||||
for _, groupName := range r.SubexpNames() {
|
||||
@@ -302,27 +301,27 @@ func isValidOperator(op PipelineOperator) error {
|
||||
}
|
||||
}
|
||||
if namedCaptureGroups == 0 {
|
||||
return fmt.Errorf("no capture groups in regex expression of %s regex operator", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "no capture groups in regex expression of %s regex operator", op.ID)
|
||||
}
|
||||
case "copy":
|
||||
if op.From == "" || op.To == "" {
|
||||
return fmt.Errorf("from or to of %s copy operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "from or to of %s copy operator cannot be empty", op.ID)
|
||||
}
|
||||
case "move":
|
||||
if op.From == "" || op.To == "" {
|
||||
return fmt.Errorf("from or to of %s move operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "from or to of %s move operator cannot be empty", op.ID)
|
||||
}
|
||||
case "add":
|
||||
if op.Field == "" || op.Value == "" {
|
||||
return fmt.Errorf("field or value of %s add operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "field or value of %s add operator cannot be empty", op.ID)
|
||||
}
|
||||
case "remove":
|
||||
if op.Field == "" {
|
||||
return fmt.Errorf("field of %s remove operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "field of %s remove operator cannot be empty", op.ID)
|
||||
}
|
||||
case "trace_parser":
|
||||
if op.TraceParser == nil {
|
||||
return fmt.Errorf("field of %s remove operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "field of %s remove operator cannot be empty", op.ID)
|
||||
}
|
||||
|
||||
hasTraceIdParseFrom := (op.TraceParser.TraceId != nil && op.TraceParser.TraceId.ParseFrom != "")
|
||||
@@ -330,42 +329,40 @@ func isValidOperator(op PipelineOperator) error {
|
||||
hasTraceFlagsParseFrom := (op.TraceParser.TraceFlags != nil && op.TraceParser.TraceFlags.ParseFrom != "")
|
||||
|
||||
if !(hasTraceIdParseFrom || hasSpanIdParseFrom || hasTraceFlagsParseFrom) {
|
||||
return fmt.Errorf("one of trace_id, span_id, trace_flags of %s trace_parser operator must be present", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "one of trace_id, span_id, trace_flags of %s trace_parser operator must be present", op.ID)
|
||||
}
|
||||
|
||||
if hasTraceIdParseFrom && !isValidOtelValue(op.TraceParser.TraceId.ParseFrom) {
|
||||
return fmt.Errorf("trace id can't be parsed from %s", op.TraceParser.TraceId.ParseFrom)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "trace id can't be parsed from %s", op.TraceParser.TraceId.ParseFrom)
|
||||
}
|
||||
if hasSpanIdParseFrom && !isValidOtelValue(op.TraceParser.SpanId.ParseFrom) {
|
||||
return fmt.Errorf("span id can't be parsed from %s", op.TraceParser.SpanId.ParseFrom)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "span id can't be parsed from %s", op.TraceParser.SpanId.ParseFrom)
|
||||
}
|
||||
if hasTraceFlagsParseFrom && !isValidOtelValue(op.TraceParser.TraceFlags.ParseFrom) {
|
||||
return fmt.Errorf("trace flags can't be parsed from %s", op.TraceParser.TraceFlags.ParseFrom)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "trace flags can't be parsed from %s", op.TraceParser.TraceFlags.ParseFrom)
|
||||
}
|
||||
|
||||
case "retain":
|
||||
if len(op.Fields) == 0 {
|
||||
return fmt.Errorf("fields of %s retain operator cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "fields of %s retain operator cannot be empty", op.ID)
|
||||
}
|
||||
|
||||
case "time_parser":
|
||||
if op.ParseFrom == "" {
|
||||
return fmt.Errorf("parse from of time parsing processor %s cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "parse from of time parsing processor %s cannot be empty", op.ID)
|
||||
}
|
||||
if op.LayoutType != "epoch" && op.LayoutType != "strptime" {
|
||||
// TODO(Raj): Maybe add support for gotime format
|
||||
return fmt.Errorf(
|
||||
"invalid format type '%s' of time parsing processor %s", op.LayoutType, op.ID,
|
||||
)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "invalid format type '%s' of time parsing processor %s", op.LayoutType, op.ID)
|
||||
}
|
||||
if op.Layout == "" {
|
||||
return fmt.Errorf("format can not be empty for time parsing processor %s", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "format can not be empty for time parsing processor %s", op.ID)
|
||||
}
|
||||
|
||||
validEpochLayouts := []string{"s", "ms", "us", "ns", "s.ms", "s.us", "s.ns"}
|
||||
if op.LayoutType == "epoch" && !slices.Contains(validEpochLayouts, op.Layout) {
|
||||
return fmt.Errorf(
|
||||
"invalid epoch format '%s' of time parsing processor %s", op.LayoutType, op.ID,
|
||||
return errors.NewInvalidInputf(
|
||||
errors.CodeInvalidInput, "invalid epoch format '%s' of time parsing processor %s", op.LayoutType, op.ID,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -374,23 +371,30 @@ func isValidOperator(op PipelineOperator) error {
|
||||
if op.LayoutType == "strptime" {
|
||||
_, err := RegexForStrptimeLayout(op.Layout)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid strptime format '%s' of time parsing processor %s: %w", op.LayoutType, op.ID, err)
|
||||
return errors.WrapInvalidInputf(
|
||||
err, errors.CodeInvalidInput, "invalid strptime format '%s' of time parsing processor %s",
|
||||
op.LayoutType, op.ID,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
case "severity_parser":
|
||||
if op.ParseFrom == "" {
|
||||
return fmt.Errorf("parse from of severity parsing processor %s cannot be empty", op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "parse from of severity parsing processor %s cannot be empty", op.ID)
|
||||
}
|
||||
|
||||
for k := range op.Mapping {
|
||||
if !slices.Contains(validMappingLevels, strings.ToLower(k)) {
|
||||
return fmt.Errorf("%s is not a valid severity in processor %s", k, op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "%s is not a valid severity in processor %s", k, op.ID)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("operator type %s not supported for %s, use one of (grok_parser, regex_parser, copy, move, add, remove, trace_parser, retain)", op.Type, op.ID)
|
||||
return errors.NewInvalidInputf(
|
||||
errors.CodeInvalidInput,
|
||||
"operator type %s not supported for %s, use one of (grok_parser, regex_parser, copy, move, add, remove, trace_parser, retain)",
|
||||
op.Type, op.ID,
|
||||
)
|
||||
}
|
||||
|
||||
if !isValidOtelValue(op.ParseFrom) ||
|
||||
@@ -399,7 +403,7 @@ func isValidOperator(op PipelineOperator) error {
|
||||
!isValidOtelValue(op.To) ||
|
||||
!isValidOtelValue(op.Field) {
|
||||
valueErrStr := "value should have prefix of body, attributes, resource"
|
||||
return fmt.Errorf("%s for operator Id %s", valueErrStr, op.ID)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "%s for operator Id %s", valueErrStr, op.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pipelinetypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@@ -114,7 +113,7 @@ func RegexForStrptimeLayout(layout string) (string, error) {
|
||||
strptimeDirectiveRegexp := regexp.MustCompile(`%.`)
|
||||
layoutRegex = strptimeDirectiveRegexp.ReplaceAllStringFunc(layoutRegex, replaceStrptimeDirectiveWithRegex)
|
||||
if len(errs) != 0 {
|
||||
return "", fmt.Errorf("couldn't generate regex for ctime format: %v", errs)
|
||||
return "", errors.NewInvalidInputf(errors.CodeInvalidInput, "couldn't generate regex for ctime format: %v", errs)
|
||||
}
|
||||
|
||||
return layoutRegex, nil
|
||||
|
||||
@@ -173,7 +173,8 @@ func (ns *NotificationSettings) UnmarshalJSON(data []byte) error {
|
||||
// Validate states after unmarshaling
|
||||
for _, state := range ns.Renotify.AlertStates {
|
||||
if state != model.StateFiring && state != model.StateNoData {
|
||||
return fmt.Errorf("invalid alert state: %s", state)
|
||||
return signozError.NewInvalidInputf(signozError.CodeInvalidInput, "invalid alert state: %s", state)
|
||||
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -290,7 +290,7 @@ func (te TemplateExpander) Expand() (result string, resultErr error) {
|
||||
var ok bool
|
||||
resultErr, ok = r.(error)
|
||||
if !ok {
|
||||
resultErr = fmt.Errorf("panic expanding template %v: %v", te.name, r)
|
||||
resultErr = errors.NewInternalf(errors.CodeInternal, "panic expanding template %v: %v", te.name, r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -299,12 +299,12 @@ func (te TemplateExpander) Expand() (result string, resultErr error) {
|
||||
|
||||
tmpl, err := text_template.New(te.name).Funcs(te.funcMap).Option("missingkey=zero").Parse(te.text)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error parsing template %v: %v", te.name, err)
|
||||
return "", errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "error parsing template %v", te.name)
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
err = tmpl.Execute(&buffer, te.data)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error executing template %v: %v", te.name, err)
|
||||
return "", errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "error executing template %v", te.name)
|
||||
}
|
||||
return buffer.String(), nil
|
||||
}
|
||||
@@ -316,7 +316,7 @@ func (te TemplateExpander) ExpandHTML(templateFiles []string) (result string, re
|
||||
var ok bool
|
||||
resultErr, ok = r.(error)
|
||||
if !ok {
|
||||
resultErr = fmt.Errorf("panic expanding template %v: %v", te.name, r)
|
||||
resultErr = errors.NewInternalf(errors.CodeInternal, "panic expanding template %v: %v", te.name, r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
@@ -332,18 +332,18 @@ func (te TemplateExpander) ExpandHTML(templateFiles []string) (result string, re
|
||||
})
|
||||
tmpl, err := tmpl.Parse(te.text)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error parsing template %v: %v", te.name, err)
|
||||
return "", errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "error parsing template %v", te.name)
|
||||
}
|
||||
if len(templateFiles) > 0 {
|
||||
_, err = tmpl.ParseFiles(templateFiles...)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error parsing template files for %v: %v", te.name, err)
|
||||
return "", errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "error parsing template files for %v", te.name)
|
||||
}
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
err = tmpl.Execute(&buffer, te.data)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error executing template %v: %v", te.name, err)
|
||||
return "", errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "error executing template %v", te.name)
|
||||
}
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package telemetrytypes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
|
||||
@@ -98,7 +98,7 @@ func (f *FieldContext) UnmarshalJSON(data []byte) error {
|
||||
// Scan implements the sql.Scanner interface
|
||||
func (f *FieldContext) Scan(value interface{}) error {
|
||||
if f == nil {
|
||||
return fmt.Errorf("fieldcontext: nil receiver")
|
||||
return errors.NewInternalf(errors.CodeInternal, "fieldcontext: nil receiver")
|
||||
}
|
||||
|
||||
if value == nil {
|
||||
@@ -108,7 +108,7 @@ func (f *FieldContext) Scan(value interface{}) error {
|
||||
|
||||
str, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("fieldcontext: expected string, got %T", value)
|
||||
return errors.NewInternalf(errors.CodeInternal, "fieldcontext: expected string, got %T", value)
|
||||
}
|
||||
|
||||
// Normalize the string
|
||||
|
||||
@@ -2,9 +2,9 @@ package telemetrytypes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
|
||||
@@ -123,7 +123,7 @@ func (f *FieldDataType) UnmarshalJSON(data []byte) error {
|
||||
// Scan implements the sql.Scanner interface
|
||||
func (f *FieldDataType) Scan(value interface{}) error {
|
||||
if f == nil {
|
||||
return fmt.Errorf("fielddatatype: nil receiver")
|
||||
return errors.NewInternalf(errors.CodeInternal, "fielddatatype: nil receiver")
|
||||
}
|
||||
|
||||
if value == nil {
|
||||
@@ -133,7 +133,7 @@ func (f *FieldDataType) Scan(value interface{}) error {
|
||||
|
||||
str, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("fielddatatype: expected string, got %T", value)
|
||||
return errors.NewInternalf(errors.CodeInternal, "fielddatatype: expected string, got %T", value)
|
||||
}
|
||||
|
||||
// Normalize the string
|
||||
|
||||
@@ -2,9 +2,9 @@ package telemetrytypestest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
|
||||
)
|
||||
|
||||
@@ -12,12 +12,12 @@ import (
|
||||
func LoadFieldKeysFromJSON(filePath string) (map[string][]*telemetrytypes.TelemetryFieldKey, error) {
|
||||
jsonData, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read JSON file: %w", err)
|
||||
return nil, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "failed to read JSON file")
|
||||
}
|
||||
|
||||
var result map[string][]*telemetrytypes.TelemetryFieldKey
|
||||
if err := json.Unmarshal(jsonData, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
|
||||
return nil, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "failed to unmarshal JSON")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
@@ -27,7 +27,7 @@ func LoadFieldKeysFromJSON(filePath string) (map[string][]*telemetrytypes.Teleme
|
||||
func LoadFieldKeysFromJSONString(jsonStr string) (map[string][]*telemetrytypes.TelemetryFieldKey, error) {
|
||||
var result map[string][]*telemetrytypes.TelemetryFieldKey
|
||||
if err := json.Unmarshal([]byte(jsonStr), &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal JSON: %w", err)
|
||||
return nil, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "failed to unmarshal JSON")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package tracefunneltypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
@@ -13,10 +12,10 @@ import (
|
||||
// ValidateTimestamp validates a timestamp
|
||||
func ValidateTimestamp(timestamp int64, fieldName string) error {
|
||||
if timestamp == 0 {
|
||||
return fmt.Errorf("%s is required", fieldName)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "%s is required", fieldName)
|
||||
}
|
||||
if timestamp < 0 {
|
||||
return fmt.Errorf("%s must be positive", fieldName)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "%s must be positive", fieldName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -28,18 +27,18 @@ func ValidateTimestampIsMilliseconds(timestamp int64) bool {
|
||||
|
||||
func ValidateFunnelSteps(steps []*FunnelStep) error {
|
||||
if len(steps) < 2 {
|
||||
return fmt.Errorf("funnel must have at least 2 steps")
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "funnel must have at least 2 steps")
|
||||
}
|
||||
|
||||
for i, step := range steps {
|
||||
if step.ServiceName == "" {
|
||||
return fmt.Errorf("step %d: service name is required", i+1)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "step %d: service name is required", i+1)
|
||||
}
|
||||
if step.SpanName == "" {
|
||||
return fmt.Errorf("step %d: span name is required", i+1)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "step %d: span name is required", i+1)
|
||||
}
|
||||
if step.Order < 0 {
|
||||
return fmt.Errorf("step %d: order must be non-negative", i+1)
|
||||
return errors.NewInvalidInputf(errors.CodeInvalidInput, "step %d: order must be non-negative", i+1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package clickhouse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/AfterShip/clickhouse-sql-parser/parser"
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
)
|
||||
|
||||
// FilterAction represents what to do with a filter containing a variable
|
||||
@@ -37,7 +37,7 @@ func (qp *QueryProcessor) ProcessQuery(query string, transformer FilterTransform
|
||||
p := parser.NewParser(query)
|
||||
stmts, err := p.ParseStmts()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse query: %w", err)
|
||||
return "", errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "failed to parse query")
|
||||
}
|
||||
|
||||
if len(stmts) == 0 {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
grammar "github.com/SigNoz/signoz/pkg/parser/grammar"
|
||||
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
|
||||
"github.com/antlr4-go/antlr/v4"
|
||||
@@ -26,7 +27,7 @@ func NewErrorListener() *ErrorListener {
|
||||
|
||||
// SyntaxError is called when a syntax error is encountered
|
||||
func (e *ErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol any, line, column int, msg string, ex antlr.RecognitionException) {
|
||||
e.SyntaxErrors = append(e.SyntaxErrors, fmt.Errorf("line %d:%d %s", line, column, msg))
|
||||
e.SyntaxErrors = append(e.SyntaxErrors, errors.NewInvalidInputf(errors.CodeInvalidInput, "line %d:%d %s", line, column, msg))
|
||||
}
|
||||
|
||||
// variableReplacementVisitor implements the visitor interface
|
||||
@@ -62,13 +63,13 @@ func ReplaceVariablesInExpression(expression string, variables map[string]qbtype
|
||||
tree := parser.Query()
|
||||
|
||||
if len(parserErrorListener.SyntaxErrors) > 0 {
|
||||
return "", fmt.Errorf("syntax errors in expression: %v", parserErrorListener.SyntaxErrors)
|
||||
return "", errors.NewInvalidInputf(errors.CodeInvalidInput, "syntax errors in expression: %v", parserErrorListener.SyntaxErrors)
|
||||
}
|
||||
|
||||
result := visitor.Visit(tree).(string)
|
||||
|
||||
if len(visitor.errors) > 0 {
|
||||
return "", fmt.Errorf("errors processing expression: %v", visitor.errors)
|
||||
return "", errors.NewInvalidInputf(errors.CodeInvalidInput, "errors processing expression: %v", visitor.errors)
|
||||
}
|
||||
|
||||
// If the entire expression should be skipped, return empty string
|
||||
|
||||
@@ -2,11 +2,11 @@ package routerweb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/http/middleware"
|
||||
"github.com/SigNoz/signoz/pkg/web"
|
||||
@@ -28,21 +28,21 @@ func NewFactory() factory.ProviderFactory[web.Web, web.Config] {
|
||||
func New(ctx context.Context, settings factory.ProviderSettings, config web.Config) (web.Web, error) {
|
||||
fi, err := os.Stat(config.Directory)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot access web directory: %w", err)
|
||||
return nil, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "cannot access web directory")
|
||||
}
|
||||
|
||||
ok := fi.IsDir()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("web directory is not a directory")
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "web directory is not a directory")
|
||||
}
|
||||
|
||||
fi, err = os.Stat(filepath.Join(config.Directory, indexFileName))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot access %q in web directory: %w", indexFileName, err)
|
||||
return nil, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "cannot access %q in web directory", indexFileName)
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) || fi.IsDir() {
|
||||
return nil, fmt.Errorf("%q does not exist", indexFileName)
|
||||
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "%q does not exist", indexFileName)
|
||||
}
|
||||
|
||||
return &provider{
|
||||
@@ -60,7 +60,7 @@ func (provider *provider) AddToRouter(router *mux.Router) error {
|
||||
),
|
||||
).GetError()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to add web to router: %w", err)
|
||||
return errors.WrapInternalf(err, errors.CodeInternal, "unable to add web to router")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user