Skip to content

Commit

Permalink
Start using coded_err in function config validation (#1197)
Browse files Browse the repository at this point in the history
  • Loading branch information
goodoldneon committed Apr 17, 2024
1 parent 0b7326d commit 9651747
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 2 deletions.
6 changes: 5 additions & 1 deletion pkg/inngest/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"time"

"github.com/inngest/inngest/pkg/consts"
"github.com/inngest/inngest/pkg/syscode"
)

func NewEventBatchConfig(conf map[string]any) (*EventBatchConfig, error) {
Expand Down Expand Up @@ -62,7 +63,10 @@ func (c EventBatchConfig) IsEnabled() bool {

func (c EventBatchConfig) IsValid() error {
if c.MaxSize < 2 {
return fmt.Errorf("batch size cannot be smaller than 2: %d", c.MaxSize)
return syscode.Error{
Code: syscode.CodeBatchSizeInvalid,
Message: fmt.Sprintf("batch size cannot be smaller than 2: %d", c.MaxSize),
}
}

if _, err := time.ParseDuration(c.Timeout); err != nil {
Expand Down
6 changes: 5 additions & 1 deletion pkg/inngest/concurrency.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/inngest/inngest/pkg/consts"
"github.com/inngest/inngest/pkg/enums"
"github.com/inngest/inngest/pkg/expressions"
"github.com/inngest/inngest/pkg/syscode"
)

// ConcurrencyLimits represents concurrency limits specified for a function.
Expand All @@ -36,7 +37,10 @@ func (c ConcurrencyLimits) PartitionConcurrency() int {

func (c ConcurrencyLimits) Validate(ctx context.Context) error {
if len(c.Limits) > consts.MaxConcurrencyLimits {
return fmt.Errorf("There are more concurrency limits specified than the allowed max of: %d", consts.MaxConcurrencyLimits)
return syscode.Error{
Code: syscode.CodeConcurrencyLimitInvalid,
Message: fmt.Sprintf("There are more concurrency limits specified than the allowed max of: %d", consts.MaxConcurrencyLimits),
}
}
for _, l := range c.Limits {
if err := l.Validate(ctx); err != nil {
Expand Down
11 changes: 11 additions & 0 deletions pkg/sdk/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/hashicorp/go-multierror"
"github.com/inngest/inngest/pkg/inngest"
"github.com/inngest/inngest/pkg/syscode"
"github.com/inngest/inngest/pkg/util"
)

Expand Down Expand Up @@ -158,6 +159,16 @@ func (f RegisterRequest) Parse(ctx context.Context) ([]*inngest.Function, error)
}
}

if err != nil {
data := syscode.DataMultiErr{}
data.Append(err)

return nil, &syscode.Error{
Code: syscode.CodeConfigInvalid,
Data: data,
}
}

return funcs, err
}

Expand Down
8 changes: 8 additions & 0 deletions pkg/syscode/codes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package syscode

const (
CodeBatchSizeInvalid = "batch_size_invalid"
CodeConcurrencyLimitInvalid = "concurrency_limit_invalid"
CodeConfigInvalid = "config_invalid"
CodeUnknown = "unknown"
)
92 changes: 92 additions & 0 deletions pkg/syscode/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package syscode

import (
"encoding/json"
"errors"
"fmt"

"github.com/hashicorp/go-multierror"
)

func fromError(err error) Error {
e := &Error{}
if !errors.As(err, e) && !errors.As(err, &e) {
e = &Error{
Code: CodeUnknown,
Message: err.Error(),
}
}

return *e
}

type Error struct {
Code string `json:"code"`
Data any `json:"data"`
Message string `json:"message"`
}

func (e Error) Error() string {
if e.Message != "" {
return e.Message
}

byt, err := json.Marshal(e.Data)
if err != nil {
return e.Code
}

msg, err := messageFromMultiErrData(byt)
if err == nil {
return msg
}

return e.Code
}

// Create an single error message from error data that contains multiple errors.
// Returns an error if the data isn't valid MultiErrData
func messageFromMultiErrData(data []byte) (string, error) {
me := &DataMultiErr{}
err := json.Unmarshal(data, me)
if err != nil {
return "", fmt.Errorf("not MultiErrData: %v", err)
}
if len(me.Errors) == 0 {
return "", errors.New("not MultiErrData")
}

// Build a string that mimics what multierror.Error does. This is for
// backcompat, since we used the multierror.Error message before we added
// the syscode package
out := fmt.Sprintf("%d errors occurred:", len(me.Errors))
for _, e := range me.Errors {
out += " * " + e.Error()
}
return out, nil
}

// Used to structure Error.Data when there are multiple errors (e.g.
// synchronization validation)
type DataMultiErr struct {
Errors []Error `json:"errors"`
}

func (e *DataMultiErr) Append(err error) {
if err == nil {
return
}

if me, ok := err.(*multierror.Error); ok {
for i := range me.Errors {
e.Append(fromError(me.Errors[i]))
}
return
}

e.Errors = append(e.Errors, fromError(err))
}

func (e *DataMultiErr) ToMap() map[string]any {
return map[string]any{"errors": e.Errors}
}

0 comments on commit 9651747

Please sign in to comment.