Code Monkey home page Code Monkey logo

Comments (15)

RussellLuo avatar RussellLuo commented on August 17, 2024

@francesconi Thanks for your attention!

validating concentrates on data validation, so the corresponding errors are also designed around data validation. For now, an error of validating consists of three parts:

  • error kind (i.e. UNSUPPORTED and INVALID)
  • field name
  • error message (customizable)

I'm wondering when a custom error (except the message itself), in practice, is needed while doing validation? Could you give me more details?

from validating.

francesconi avatar francesconi commented on August 17, 2024

Let's say you have a custom error with a dynamic string

type NotFoundError struct {
    File string
}

func (e *NotFoundError) Error() string {
    return fmt.Sprintf("file %q not found", e.File)
}

you would be able to match it with errors.As.

for _, err := v.Validate(...) {
    var notFound *NotFoundError
    if errors.As(err, &notFound) {
        // handle the error
    } else {
        panic("unknown error")
    }
}

And you could still use errors.Is to match and handle errors with a static string.

How would you achieve this with the current implementation? I know this is a bit more than just validating but IMHO this approach would open the door to a lot more usecases.

from validating.

RussellLuo avatar RussellLuo commented on August 17, 2024

Thanks for the details! How will .Err(err error), if supported, be used along with NotFoundError in the schema definition? What does the code look like in your example?

from validating.

francesconi avatar francesconi commented on August 17, 2024

Based on the previous example something like this

(untested)

type Foo struct {
    File string
}

func (f *Foo) Schema(whitelist []string) v.Schema {
    return v.Schema{
        v.F("file", p.File): v.In(whitelist).Err(&NotFoundError{File: p.File}),
    }
}

func main() {
    whitelist := []string{"a", "b", "c"}

    f := Foo{}
    errs := v.Validate(f.Schema(whitelist))
}

from validating.

RussellLuo avatar RussellLuo commented on August 17, 2024

If it's just a matter of dynamic message strings, I guess maybe we can do something like this:

[play]

package main

import (
	"fmt"

	v "github.com/RussellLuo/validating/v3"
)

type Foo struct {
	File string
}

func (f *Foo) Schema(whitelist []string) v.Schema {
	return v.Schema{
		v.F("file", f.File): v.In(whitelist...).Msg(fmt.Sprintf("file %q not found", f.File)),
	}
}

func main() {
	whitelist := []string{"a", "b", "c"}

	f := Foo{}
	errs := v.Validate(f.Schema(whitelist))
	fmt.Printf("errs: %#v\n", errs)

	// Output:
	// errs: validating.Errors{validating.errorImpl{field:"file", kind:"INVALID", message:"file \"\" not found"}}
}

from validating.

francesconi avatar francesconi commented on August 17, 2024

The whole point about this is matching an error with a dynamic string

type Foo struct {
    File string
}

func (f *Foo) Schema(whitelist []string) v.Schema {
    return v.Schema{
        v.F("file", p.File): v.In(whitelist).Err(&NotFoundError{File: p.File}),
    }
}

func main() {
    whitelist := []string{"a", "b", "c"}

    f := Foo{}
    for _, err := v.Validate(f.Schema(whitelist)) {
        var notFound *NotFoundError
        if errors.As(err, &notFound) {
            // handle the error
        }
    }
}

Again, how would you achieve this with just a dynamic message string?

from validating.

RussellLuo avatar RussellLuo commented on August 17, 2024

Actually, what I'm trying to understand is why distinguishing different errors matters, in the scenario of data validation, if all of errors essentially are of the same kind (e.g. INVLIAD means the field is invalid).

In other words, does NotFoundError, OutOfRangeError or XxxError carry any extra information that's useful for further processing? If this is the case, I think maybe adding "error details" (similar to Google API's Error Design) is an option? (Arbitrarily custom error is very flexible, but at the cost of being non-canonical and too granular.)

from validating.

francesconi avatar francesconi commented on August 17, 2024

I've just had a look into Google API's Error Design about error details and I must admit that they would work fine for me 👍

from validating.

RussellLuo avatar RussellLuo commented on August 17, 2024

Thanks for your feedback! Adding error details seems good, but will also introduce complexity.

For a better understanding of your problem, could you please expand the part // handle the error? That is, in your concrete example, how will the handling of NotFoundError be different from other built-in INVALID errors?

from validating.

francesconi avatar francesconi commented on August 17, 2024

A client sends us availabilities for it's hotel rooms. When a certain room does not exists on our side RoomNotFound I can request the client to resend me all rooms it has on record so that the availabilities request will go through the next time.

type RoomNotFoundError struct {
    RoomCode string
}

func (e *RoomNotFoundError) Error() string {
    return fmt.Sprintf("room %s not found", e.RoomCode)
}

We do communicate with the OTA standard and my errors must have a code and a message accordingly ERR.

from validating.

RussellLuo avatar RussellLuo commented on August 17, 2024

Let me try to construct the validation flow at the server side:

  1. Handle a request containing a room code from client
  2. Validate the room code (using validating's schema)
  3. If the room code is invalid (non-existent), request the client to resend all rooms
    • In this step, is the INVALID information enough for you to make the request? Do you need the value of room code to achieve this?

from validating.

francesconi avatar francesconi commented on August 17, 2024

Would be enough if one room is missing but if more rooms are missing i'll get duplicate error messages

// Output:
// err[0]: INVALID(room not found)
// err[1]: INVALID(room not found)

from validating.

RussellLuo avatar RussellLuo commented on August 17, 2024

If the reaction to any error is to request the client to resend all rooms, I guess the whole operation will be idempotent, i.e., the result will be the same no matter how many rooms are missing, right?

As for the duplicate error messages, what's the corresponding schema definition? Does the method #10 (comment) help in this scenario?

from validating.

francesconi avatar francesconi commented on August 17, 2024

The only solution I see for now is using a static error for RoomNotFound in order to request the client to resend all rooms but our support team won't be happy at all having to read these vague error messages.

from validating.

RussellLuo avatar RussellLuo commented on August 17, 2024

The only solution I see for now is using a static error for RoomNotFound ... but our support team won't be happy to read these vague error messages.

Per the literal description, the problem seems to be the duplicate static messages, which I think should be resolved by the method mentioned in #10 (comment). If it's not the case, I think I still didn't catch the point.

Is there any minimal (and runnable) code that can reproduce the crux of the problem? I think it will be easier to find out the problem with the code, and to figure out the solution :)

from validating.

Related Issues (3)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.