Hi, I see you add Errors to ctx, but I'm thinking what gin does may not a good idea.
Basically, when we get an error, we just want to return from route handler.
Collecting errors like gin seems doesn't make sense
Golang's team offered a best practice on their blog about handling errors: Errors are values
Their solution is: define a single error object in a top level struct ( which should be in ctx in our cases )
So we can do something like this:
ctx.Error := SomeFunc()
// we don't need to deal with error here, a middleware will handle it automatically
if ctx.Error != nil { return 0, nil}
But with ctx.Errors, I have to write more code:
err := SomeFunc()
if err != nil {
ctx.Error(err)
return 0, nil
}
If we handle it with ctx.Errors[0]:
ctx.Errors := make([]error, 1)
ctx.Errors[0] := SomeFunc()
In this way, ctx.HasErrors() will always be true even if ctx.Errors[0] is nil
Following golang team's strategy, with a single ctx.Error, we can even do something like this:
func SomeFunc(param1, param2, err) error {
//check error first
if err != nil {return}
//do something
}
func SomeFunc2(param1, param2, err) error {
if err != nil {return}
//do something else
}
ctx.Error := SomeFunc(param1, param2, ctx.Error)
ctx.Error := SomeFunc2(param1, param2, ctx.Error)
ctx.Error := SomeFunc3(param1, param2, ctx.Error)
return 200, ctx.Text("done")
//then, middleware will handle ctx.Error, if there is one.
In this way, we don't need to check ctx.Error at all, since every function has checked that error at beginning, if there is an error, all those functions will just return.
I think golang team's solution is much better than gin's, a single ctx.Error may truely better than collecting all errors.