Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: error printing #43

Merged
merged 2 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ type User2 struct {
- The refine method for providing a custom validation function is renamed to `schema.Test()`
- schemas are optional by default (in zod they are required)
- The `z.Enum()` type from zod is removed in favor of `z.String().OneOf()` and is only supported for strings and numbers
- `string().regex` is renamed to `z.String().Match()` as that is in line with the regexp methods from the standard library (i.e `regexp.Match` and `regexp.MatchString()`)

## Limitations

Expand Down Expand Up @@ -325,8 +326,9 @@ type ZogError interface {
Params() map[string]any // params for the error as defined by
Message() string
SetMessage(string)
Error() string // returns the string of the wrapped error
Unwrap() error // returns the wrapped error
Error() string // returns the string representation of the ZogError. The same as String(). Printf will not print correctly otherwise.
String() string // returns the string representation of the ZogError. Example: "ZogError{Code: '', ...}"
Unwrap() error // returns the wrapped error.
}
```

Expand Down
32 changes: 25 additions & 7 deletions internals/errors.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
package internals

import (
"fmt"

zconst "github.com/Oudwins/zog/zconst"
)

// Error interface returned from all processors
type ZogError interface {
// returns the error code for the error. This is a unique identifier for the error. Generally also the ID for the Test that caused the error.
Code() zconst.ZogErrCode
Value() any // the error value
Dtype() string // destination type
// returns the data value that caused the error.
// if using Schema.Parse(data, dest) then this will be the value of data.
Value() any
// Returns destination type. i.e The zconst.ZogType of the value that was validated.
// if Using Schema.Parse(data, dest) then this will be the type of dest.
Dtype() string
// returns the params map for the error. Taken from the Test that caused the error. This may be nil if Test has no params.
Params() map[string]any
// returns the human readable, user-friendly message for the error. This is safe to expose to the user.
Message() string
// sets the human readable, user-friendly message for the error. This is safe to expose to the user.
SetMessage(string)
// returns the string of the wrapped error if any
// returns the string representation of the ZogError (same as String())
Error() string
// returns the wrapped error if any
// returns the wrapped error or nil if none
Unwrap() error
// returns the string representation of the ZogError (same as Error())
String() string
}

// this is the function that formats the error message given a zog error
type ErrFmtFunc = func(e ZogError, p ParseCtx)

// Error implementation
// INTERNAL ONLY: Error implementation
type ZogErr struct {
C zconst.ZogErrCode // error code
ParamsM map[string]any // params for the error (e.g. min, max, len, etc)
Expand Down Expand Up @@ -69,14 +81,20 @@ func (e *ZogErr) SetMessage(msg string) {
e.Msg = msg
}
func (e *ZogErr) Error() string {
return e.Err.Error()
return e.String()
}
func (e *ZogErr) Unwrap() error {
return e.Err
}

// list of errors. This is returned for each specific processor
func (e *ZogErr) String() string {
return fmt.Sprintf("ZogError{Code: %v, Params: %v, Type: %v, Value: %v, Message: '%v', Error: %v}", SafeString(e.C), SafeString(e.ParamsM), SafeString(e.Typ), SafeString(e.Val), SafeString(e.Msg), SafeError(e.Err))
}

// list of errors. This is returned by processors for simple types (e.g. strings, numbers, booleans)
type ZogErrList = []ZogError

// map of errors. This is returned by processors for complex types (e.g. maps, slices, structs)
type ZogErrMap = map[string][]ZogError

// INTERNAL ONLY: Interface used to add errors during parsing & validation. It represents a group of errors (map or slice)
Expand Down
19 changes: 18 additions & 1 deletion internals/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package internals

import "reflect"
import (
"fmt"
"reflect"
)

// checks that the value is the zero value for its type
func IsZeroValue(x any) bool {
Expand All @@ -17,3 +20,17 @@ func IsZeroValue(x any) bool {
zeroValue := reflect.Zero(v.Type())
return reflect.DeepEqual(v.Interface(), zeroValue.Interface())
}

func SafeString(x any) string {
if x == nil {
return "<nil>"
}
return fmt.Sprintf("%v", x)
}

func SafeError(x error) string {
if x == nil {
return "<nil>"
}
return x.Error()
}
Loading