removed obsolete errors

This commit is contained in:
Stephan D
2025-11-18 00:20:25 +01:00
parent ebb40c8e9b
commit 363e9afc0a
14 changed files with 82 additions and 57 deletions

BIN
api/.DS_Store vendored

Binary file not shown.

View File

@@ -3,11 +3,11 @@ package client
import (
"context"
"crypto/tls"
"errors"
"fmt"
"strings"
"time"
"github.com/tech/sendico/pkg/merrors"
fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1"
@@ -88,7 +88,7 @@ type oracleClient struct {
func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, error) {
cfg.setDefaults()
if strings.TrimSpace(cfg.Address) == "" {
return nil, errors.New("oracle: address is required")
return nil, merrors.InvalidArgument("oracle: address is required")
}
dialCtx, cancel := context.WithTimeout(ctx, cfg.DialTimeout)
@@ -105,7 +105,7 @@ func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, erro
conn, err := grpc.DialContext(dialCtx, cfg.Address, dialOpts...)
if err != nil {
return nil, fmt.Errorf("oracle: dial %s: %w", cfg.Address, err)
return nil, merrors.InternalWrap(err, fmt.Sprintf("oracle: dial %s", cfg.Address))
}
return &oracleClient{
@@ -133,7 +133,7 @@ func (c *oracleClient) Close() error {
func (c *oracleClient) LatestRate(ctx context.Context, req LatestRateParams) (*RateSnapshot, error) {
if req.Pair == nil {
return nil, errors.New("oracle: pair is required")
return nil, merrors.InvalidArgument("oracle: pair is required")
}
callCtx, cancel := c.callContext(ctx)
@@ -145,26 +145,26 @@ func (c *oracleClient) LatestRate(ctx context.Context, req LatestRateParams) (*R
Provider: req.Provider,
})
if err != nil {
return nil, fmt.Errorf("oracle: latest rate: %w", err)
return nil, merrors.InternalWrap(err, "oracle: latest rate")
}
if resp.GetRate() == nil {
return nil, errors.New("oracle: latest rate: empty payload")
return nil, merrors.Internal("oracle: latest rate: empty payload")
}
return fromProtoRate(resp.GetRate()), nil
}
func (c *oracleClient) GetQuote(ctx context.Context, req GetQuoteParams) (*Quote, error) {
if req.Pair == nil {
return nil, errors.New("oracle: pair is required")
return nil, merrors.InvalidArgument("oracle: pair is required")
}
if req.Side == fxv1.Side_SIDE_UNSPECIFIED {
return nil, errors.New("oracle: side is required")
return nil, merrors.InvalidArgument("oracle: side is required")
}
baseSupplied := req.BaseAmount != nil
quoteSupplied := req.QuoteAmount != nil
if baseSupplied == quoteSupplied {
return nil, errors.New("oracle: exactly one of base_amount or quote_amount must be set")
return nil, merrors.InvalidArgument("oracle: exactly one of base_amount or quote_amount must be set")
}
callCtx, cancel := c.callContext(ctx)
@@ -191,10 +191,10 @@ func (c *oracleClient) GetQuote(ctx context.Context, req GetQuoteParams) (*Quote
resp, err := c.client.GetQuote(callCtx, protoReq)
if err != nil {
return nil, fmt.Errorf("oracle: get quote: %w", err)
return nil, merrors.InternalWrap(err, "oracle: get quote")
}
if resp.GetQuote() == nil {
return nil, errors.New("oracle: get quote: empty payload")
return nil, merrors.Internal("oracle: get quote: empty payload")
}
return fromProtoQuote(resp.GetQuote()), nil
}

View File

@@ -3,11 +3,11 @@ package client
import (
"context"
"crypto/tls"
"errors"
"fmt"
"strings"
"time"
"github.com/tech/sendico/pkg/merrors"
ledgerv1 "github.com/tech/sendico/pkg/proto/ledger/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
@@ -48,7 +48,7 @@ type ledgerClient struct {
func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, error) {
cfg.setDefaults()
if strings.TrimSpace(cfg.Address) == "" {
return nil, errors.New("ledger: address is required")
return nil, merrors.InvalidArgument("ledger: address is required")
}
dialCtx, cancel := context.WithTimeout(ctx, cfg.DialTimeout)
@@ -65,7 +65,7 @@ func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, erro
conn, err := grpc.DialContext(dialCtx, cfg.Address, dialOpts...)
if err != nil {
return nil, fmt.Errorf("ledger: dial %s: %w", cfg.Address, err)
return nil, merrors.InternalWrap(err, fmt.Sprintf("ledger: dial %s", cfg.Address))
}
return &ledgerClient{

View File

@@ -146,7 +146,7 @@ func calculateBalance(lines []*model.PostingLine) (decimal.Decimal, error) {
for _, line := range lines {
amount, err := parseDecimal(line.Amount)
if err != nil {
return decimal.Zero, fmt.Errorf("invalid line amount: %w", err)
return decimal.Zero, merrors.InvalidArgumentWrap(err, "invalid line amount")
}
balance = balance.Add(amount)
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/tech/sendico/ledger/storage"
ledgerModel "github.com/tech/sendico/ledger/storage/model"
"github.com/tech/sendico/pkg/merrors"
pmessaging "github.com/tech/sendico/pkg/messaging"
me "github.com/tech/sendico/pkg/messaging/envelope"
"github.com/tech/sendico/pkg/mlogger"
@@ -126,7 +127,7 @@ func (p *outboxPublisher) dispatchPending(ctx context.Context) (int, error) {
func (p *outboxPublisher) publishEvent(_ context.Context, event *ledgerModel.OutboxEvent) error {
docID := event.GetID()
if docID == nil || docID.IsZero() {
return errors.New("outbox event missing identifier")
return merrors.InvalidArgument("outbox event missing identifier")
}
payload, err := p.wrapPayload(event)
@@ -157,7 +158,7 @@ func (p *outboxPublisher) wrapPayload(event *ledgerModel.OutboxEvent) ([]byte, e
func (p *outboxPublisher) markSent(ctx context.Context, event *ledgerModel.OutboxEvent) error {
eventRef := event.GetID()
if eventRef == nil || eventRef.IsZero() {
return errors.New("outbox event missing identifier")
return merrors.InvalidArgument("outbox event missing identifier")
}
return p.store.MarkSent(ctx, *eventRef, time.Now().UTC())

View File

@@ -249,15 +249,15 @@ func (s *Service) getStatementResponder(_ context.Context, req *ledgerv1.GetStat
func parseCursor(cursor string) (int, error) {
decoded, err := base64.StdEncoding.DecodeString(cursor)
if err != nil {
return 0, fmt.Errorf("invalid base64: %w", err)
return 0, merrors.InvalidArgumentWrap(err, "invalid cursor base64 encoding")
}
parts := strings.Split(string(decoded), ":")
if len(parts) != 2 || parts[0] != "offset" {
return 0, fmt.Errorf("invalid cursor format")
return 0, merrors.InvalidArgument("invalid cursor format")
}
offset, err := strconv.Atoi(parts[1])
if err != nil {
return 0, fmt.Errorf("invalid offset: %w", err)
return 0, merrors.InvalidArgumentWrap(err, "invalid cursor offset")
}
return offset, nil
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/tech/sendico/ledger/storage"
"github.com/tech/sendico/pkg/api/routers"
"github.com/tech/sendico/pkg/merrors"
pmessaging "github.com/tech/sendico/pkg/messaging"
"github.com/tech/sendico/pkg/mlogger"
ledgerv1 "github.com/tech/sendico/pkg/proto/ledger/v1"
@@ -241,10 +242,10 @@ func (s *Service) quoteFees(ctx context.Context, trigger feesv1.Trigger, organiz
return nil, nil
}
if strings.TrimSpace(organizationRef) == "" {
return nil, fmt.Errorf("organization reference is required to quote fees")
return nil, merrors.InvalidArgument("organization reference is required to quote fees")
}
if baseAmount == nil {
return nil, fmt.Errorf("base amount is required to quote fees")
return nil, merrors.InvalidArgument("base amount is required to quote fees")
}
amountCopy := &moneyv1.Money{Amount: baseAmount.GetAmount(), Currency: baseAmount.GetCurrency()}
@@ -309,11 +310,11 @@ func convertFeeDerivedLines(lines []*feesv1.DerivedPostingLine) ([]*ledgerv1.Pos
continue
}
if line.GetMoney() == nil {
return nil, fmt.Errorf("fee line %d missing money", idx)
return nil, merrors.Internal(fmt.Sprintf("fee line %d missing money", idx))
}
dec, err := decimal.NewFromString(line.GetMoney().GetAmount())
if err != nil {
return nil, fmt.Errorf("fee line %d invalid amount: %w", idx, err)
return nil, merrors.InternalWrap(err, fmt.Sprintf("fee line %d invalid amount", idx))
}
dec = ensureAmountForSide(dec, line.GetSide())
posting := &ledgerv1.PostingLine{

View File

@@ -2,12 +2,12 @@ package notificationimp
import (
"context"
"fmt"
"github.com/tech/sendico/notification/interface/api"
mmail "github.com/tech/sendico/notification/internal/server/notificationimp/mail"
"github.com/tech/sendico/notification/internal/server/notificationimp/telegram"
"github.com/tech/sendico/pkg/domainprovider"
"github.com/tech/sendico/pkg/merrors"
na "github.com/tech/sendico/pkg/messaging/notifications/account"
ni "github.com/tech/sendico/pkg/messaging/notifications/invitation"
snotifications "github.com/tech/sendico/pkg/messaging/notifications/site"
@@ -39,10 +39,10 @@ func CreateAPI(a api.API) (*NotificationAPI, error) {
p.logger = a.Logger().Named(p.Name())
if a.Config().Notification == nil {
return nil, fmt.Errorf("notification configuration is missing")
return nil, merrors.InvalidArgument("notification configuration is missing")
}
if a.Config().Notification.Telegram == nil {
return nil, fmt.Errorf("telegram configuration is missing")
return nil, merrors.InvalidArgument("telegram configuration is missing")
}
var err error
@@ -90,7 +90,7 @@ func CreateAPI(a api.API) (*NotificationAPI, error) {
func (a *NotificationAPI) onDemoRequest(ctx context.Context, request *model.DemoRequest) error {
if a.tg == nil {
return fmt.Errorf("telegram client is not configured")
return merrors.Internal("telegram client is not configured")
}
if err := a.tg.SendDemoRequest(ctx, request); err != nil {
a.logger.Warn("Failed to send demo request via telegram", zap.Error(err))

View File

@@ -13,6 +13,7 @@ import (
"time"
notconfig "github.com/tech/sendico/notification/interface/services/notification/config"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
)
@@ -45,15 +46,15 @@ type sendMessagePayload struct {
func NewClient(logger mlogger.Logger, cfg *notconfig.TelegramConfig) (Client, error) {
if cfg == nil {
return nil, fmt.Errorf("telegram configuration is not provided")
return nil, merrors.InvalidArgument("telegram configuration is not provided")
}
token := strings.TrimSpace(os.Getenv(cfg.BotTokenEnv))
if token == "" {
return nil, fmt.Errorf("telegram bot token env %s is empty", cfg.BotTokenEnv)
return nil, merrors.InvalidArgument(fmt.Sprintf("telegram bot token env %s is empty", cfg.BotTokenEnv))
}
chatID := strings.TrimSpace(os.Getenv(cfg.ChatIDEnv))
if chatID == "" {
return nil, fmt.Errorf("telegram chat id env %s is empty", cfg.ChatIDEnv)
return nil, merrors.InvalidArgument(fmt.Sprintf("telegram chat id env %s is empty", cfg.ChatIDEnv))
}
var threadID *int64
@@ -62,7 +63,7 @@ func NewClient(logger mlogger.Logger, cfg *notconfig.TelegramConfig) (Client, er
if raw != "" {
val, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
return nil, fmt.Errorf("telegram thread id env %s is invalid: %w", env, err)
return nil, merrors.InvalidArgumentWrap(err, fmt.Sprintf("telegram thread id env %s is invalid", env))
}
threadID = &val
}
@@ -93,7 +94,7 @@ func NewClient(logger mlogger.Logger, cfg *notconfig.TelegramConfig) (Client, er
func (c *client) SendDemoRequest(ctx context.Context, request *model.DemoRequest) error {
if request == nil {
return fmt.Errorf("demo request payload is nil")
return merrors.InvalidArgument("demo request payload is nil")
}
message := buildMessage(request)
payload := sendMessagePayload{
@@ -127,7 +128,7 @@ func (c *client) sendMessage(ctx context.Context, payload sendMessagePayload) er
return nil
}
respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 4<<10))
return fmt.Errorf("telegram sendMessage failed with status %d: %s", resp.StatusCode, string(respBody))
return merrors.Internal(fmt.Sprintf("telegram sendMessage failed with status %d: %s", resp.StatusCode, string(respBody)))
}
func (c *client) endpoint() string {

View File

@@ -3,11 +3,11 @@ package client
import (
"context"
"crypto/tls"
"errors"
"fmt"
"strings"
"time"
"github.com/tech/sendico/pkg/merrors"
orchestratorv1 "github.com/tech/sendico/pkg/proto/payments/orchestrator/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
@@ -48,7 +48,7 @@ type orchestratorClient struct {
func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, error) {
cfg.setDefaults()
if strings.TrimSpace(cfg.Address) == "" {
return nil, errors.New("payment-orchestrator: address is required")
return nil, merrors.InvalidArgument("payment-orchestrator: address is required")
}
dialCtx, cancel := context.WithTimeout(ctx, cfg.DialTimeout)
@@ -65,7 +65,7 @@ func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, erro
conn, err := grpc.DialContext(dialCtx, cfg.Address, dialOpts...)
if err != nil {
return nil, fmt.Errorf("payment-orchestrator: dial %s: %w", cfg.Address, err)
return nil, merrors.InternalWrap(err, fmt.Sprintf("payment-orchestrator: dial %s", cfg.Address))
}
return &orchestratorClient{

View File

@@ -49,13 +49,13 @@ func AccessDenied(object, action string, objectRef primitive.ObjectID) error {
var ErrInvalidDataType = errors.New("invalidDataType")
func InvalidDataType(msg string) error {
return fmt.Errorf("%w: %s", ErrDataConflict, msg)
return fmt.Errorf("%w: %s", ErrInvalidDataType, msg)
}
var ErrUnauthorized = errors.New("unathorized")
func Unauthorized(msg string) error {
return fmt.Errorf("%w: %s", ErrDataConflict, msg)
return fmt.Errorf("%w: %s", ErrUnauthorized, msg)
}
var ErrNoMessagingTopic = errors.New("messagingTopicError")
@@ -63,3 +63,19 @@ var ErrNoMessagingTopic = errors.New("messagingTopicError")
func NoMessagingTopic(topic string) error {
return fmt.Errorf("%w: messaging topic '%s' not found", ErrNoMessagingTopic, topic)
}
func InvalidArgumentWrap(err error, msg string) error {
return wrapError(ErrInvalidArg, msg, err)
}
func InternalWrap(err error, msg string) error {
return wrapError(ErrInternal, msg, err)
}
func wrapError(base error, msg string, err error) error {
baseErr := fmt.Errorf("%w: %s", base, msg)
if err == nil {
return baseErr
}
return errors.Join(baseErr, err)
}

View File

@@ -1,9 +1,8 @@
package notifications
import (
"fmt"
gmessaging "github.com/tech/sendico/pkg/generated/gmessaging"
"github.com/tech/sendico/pkg/merrors"
messaging "github.com/tech/sendico/pkg/messaging/envelope"
"github.com/tech/sendico/pkg/model"
nm "github.com/tech/sendico/pkg/model/notification"
@@ -18,7 +17,7 @@ type DemoRequestNotification struct {
func (drn *DemoRequestNotification) Serialize() ([]byte, error) {
if drn.request == nil {
return nil, fmt.Errorf("demo request payload is empty")
return nil, merrors.InvalidArgument("demo request payload is empty")
}
msg := gmessaging.DemoRequestEvent{
Name: drn.request.Name,

View File

@@ -12,6 +12,7 @@ type Config struct {
}
type ChainGatewayConfig struct {
Address string `yaml:"address"`
AddressEnv string `yaml:"address_env"`
DialTimeoutSeconds int `yaml:"dial_timeout_seconds"`
CallTimeoutSeconds int `yaml:"call_timeout_seconds"`

View File

@@ -16,6 +16,7 @@ import (
"github.com/tech/sendico/pkg/db/refreshtokens"
"github.com/tech/sendico/pkg/db/transaction"
"github.com/tech/sendico/pkg/domainprovider"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/messaging"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/mservice"
@@ -142,7 +143,12 @@ func CreateAPI(a eapi.API) (*AccountAPI, error) {
}
p.accountsPermissionRef = accountsPolicy.ID
if err := p.initChainGateway(a.Config()); err != nil {
cfg := a.Config()
if cfg == nil {
p.logger.Error("Failed to fetch service configuration")
return nil, merrors.InvalidArgument("No configuration provided")
}
if err := p.initChainGateway(cfg.ChainGateway); err != nil {
p.logger.Error("Failed to initialize chain gateway client", zap.Error(err))
return nil, err
}
@@ -150,21 +156,21 @@ func CreateAPI(a eapi.API) (*AccountAPI, error) {
return p, nil
}
func (a *AccountAPI) initChainGateway(cfg *eapi.Config) error {
if cfg == nil || cfg.ChainGateway == nil {
return fmt.Errorf("chain gateway configuration is not provided")
func (a *AccountAPI) initChainGateway(cfg *eapi.ChainGatewayConfig) error {
if cfg == nil {
return merrors.InvalidArgument("chain gateway configuration is not provided")
}
address := strings.TrimSpace(os.Getenv(cfg.ChainGateway.AddressEnv))
address := strings.TrimSpace(os.Getenv(cfg.AddressEnv))
if address == "" {
return fmt.Errorf("chain gateway address env %s is empty", cfg.ChainGateway.AddressEnv)
return merrors.InvalidArgument(fmt.Sprintf("chain gateway address env %s is empty", cfg.AddressEnv))
}
clientCfg := chaingatewayclient.Config{
Address: address,
DialTimeout: time.Duration(cfg.ChainGateway.DialTimeoutSeconds) * time.Second,
CallTimeout: time.Duration(cfg.ChainGateway.CallTimeoutSeconds) * time.Second,
Insecure: cfg.ChainGateway.Insecure,
DialTimeout: time.Duration(cfg.DialTimeoutSeconds) * time.Second,
CallTimeout: time.Duration(cfg.CallTimeoutSeconds) * time.Second,
Insecure: cfg.Insecure,
}
client, err := chaingatewayclient.New(context.Background(), clientCfg)
@@ -172,7 +178,7 @@ func (a *AccountAPI) initChainGateway(cfg *eapi.Config) error {
return err
}
asset, err := buildGatewayAsset(cfg.ChainGateway.DefaultAsset)
asset, err := buildGatewayAsset(cfg.DefaultAsset)
if err != nil {
_ = client.Close()
return err
@@ -190,7 +196,7 @@ func buildGatewayAsset(cfg eapi.ChainGatewayAssetConfig) (*gatewayv1.Asset, erro
}
tokenSymbol := strings.TrimSpace(cfg.TokenSymbol)
if tokenSymbol == "" {
return nil, fmt.Errorf("chain gateway token symbol is required")
return nil, merrors.InvalidArgument("chain gateway token symbol is required")
}
return &gatewayv1.Asset{
Chain: chain,
@@ -208,8 +214,8 @@ func parseChainNetwork(value string) (gatewayv1.ChainNetwork, error) {
case "OTHER_EVM", "CHAIN_NETWORK_OTHER_EVM":
return gatewayv1.ChainNetwork_CHAIN_NETWORK_OTHER_EVM, nil
case "", "CHAIN_NETWORK_UNSPECIFIED":
return gatewayv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED, fmt.Errorf("chain network must be specified")
return gatewayv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED, merrors.InvalidArgument("chain network must be specified")
default:
return gatewayv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED, fmt.Errorf("unsupported chain network %s", value)
return gatewayv1.ChainNetwork_CHAIN_NETWORK_UNSPECIFIED, merrors.InvalidArgument("unsupported chain network %s", value)
}
}