如何从 Golang 的错误方法中返回结构体

huangapple go评论80阅读模式
英文:

How to return struct from golang error method

问题

我正在使用Echo框架编写一个简单的REST API来处理路由。我试图使用中间件来实现集中式的错误处理。在下面的代码中,在错误方法的实现中,我想返回一个结构体,以便我可以在自定义错误处理程序中使用该信息。

main.go

package main

import (
	"fmt"
	"net/http"

	"github.com/labstack/echo"
	log "github.com/sirupsen/logrus"
)

func main() {
	e := echo.New()
	e.GET("/process", PostHandler)
	e.HTTPErrorHandler = customHTTPErrorHandler

	log.Fatal(e.Start(":3000"))
}

func PostHandler(ctx echo.Context) error {
	x := 0
	if x != 0 {
		return NewTypeError(1024, "Invalid arguments")
	}
	return ctx.JSON(http.StatusOK, "message")
}

func customHTTPErrorHandler(err error, c echo.Context) {
	fmt.Println("Inside custom error")
	fmt.Println(err)
}

error.go

package main

import "fmt"

type Error struct {
	Message  string
	Internal int
}

func (e *Error) Error() string {
	fmt.Println("Hello error")
	return "error"
}

func NewTypeError(Internal int, Message string) *Error {
	fmt.Println(Internal)
	fmt.Println(Message)
	return &Error{
		Message,
		Internal,
	}
}

我希望我的输出JSON响应从自定义错误中间件发送,如下所示:

{
	"code": "1024",
	"message": "Invalid Arguments"
}
英文:

I am writing a simple rest api using echo framework for route handling. I am trying to maintain centralised error handling using middlewares. In the following code, in the error method implementation I want to return a struct so that I can use that info in custom error Handler

main.go

package main
import log "github.com/sirupsen/logrus"
import "github.com/labstack/echo"
import "net/http"
import "fmt"

func main(){
e := echo.New()
e.GET("process", PostHandler)
e.HTTPErrorHandler = customHTTPErrorHandler

log.Fatal(e.Start(":3000"))
}

func PostHandler(ctx echo.Context) error{
 x:= 0;
 if x != 0 {
	return  NewTypeError(1024, "Invalid arguments")
 }
 return ctx.JSON(http.StatusOK, "message")
}

func customHTTPErrorHandler(err error, c echo.Context) {
	fmt.Println("Inside custom error")
	fmt.Println(err);
}

error.go

package main
import "fmt"
type Error struct{
	Message string
	Internal int
}

func (e *Error)Error() string{
	fmt.Println("Hello error")
	return "error"
}

func NewTypeError( Internal int, Message string) *Error {
	fmt.Println(Internal)
	fmt.Println(Message)
    return &Error{
        
		Message,
		Internal,
       
    }
}

I want my output json response to be sent from custom error middleware like this.

{
code: "1024",
message: "Invalid Arguments"
}

答案1

得分: 2

c.JSON添加到customHTTPErrorHandler中,并在struct Error中添加json标签。

// main.go

package main

import (
	"fmt"
	"net/http"

	"github.com/labstack/echo"
	log "github.com/sirupsen/logrus"
)

func main() {
	e := echo.New()
	e.GET("process", PostHandler)
	e.HTTPErrorHandler = customHTTPErrorHandler

	log.Fatal(e.Start(":3000"))
}

func PostHandler(ctx echo.Context) error {
	x := 0
	if x == 0 {
		return NewTypeError(http.StatusInternalServerError, 1024, "Invalid arguments")
	}
	return ctx.JSON(http.StatusOK, "message")
}

func customHTTPErrorHandler(err error, c echo.Context) {
	fmt.Println("Inside custom error")

	var rerr *Error

	switch e := err.(type) {
	case *Error:
		rerr = e
	case *echo.HTTPError:
		// todo: improve error conversion
		rerr = NewTypeError(e.Code, EchoHttpError, e.Error())
	default:
		rerr = NewTypeError(http.StatusInternalServerError, InternalError, e.Error())
	}

	c.JSON(rerr.Code, rerr)
}
// error.go

package main

import (
	"fmt"
)

const (
	EchoHttpError int = iota
	InternalError
)

type Error struct {
	Code     int    `json:"-"`
	Message  string `json:"message"`
	Internal int    `json:"internal"`
}

func (e *Error) Error() string {
	fmt.Println("Hello error")
	return "error"
}

func NewTypeError(code int, internal int, message string) *Error {
	fmt.Println(internal)
	fmt.Println(message)
	return &Error{
		Code:     code,
		Message:  message,
		Internal: internal,
	}
}
英文:

Add c.JSON to customHTTPErrorHandler and add json tags to struct Error.

// main.go

package main

import (
	"fmt"
	"net/http"

	"github.com/labstack/echo"
	log "github.com/sirupsen/logrus"
)

func main() {
	e := echo.New()
	e.GET("process", PostHandler)
	e.HTTPErrorHandler = customHTTPErrorHandler

	log.Fatal(e.Start(":3000"))
}

func PostHandler(ctx echo.Context) error {
	x := 0
	if x == 0 {
		return NewTypeError(http.StatusInternalServerError, 1024, "Invalid arguments")
	}
	return ctx.JSON(http.StatusOK, "message")
}

func customHTTPErrorHandler(err error, c echo.Context) {
	fmt.Println("Inside custom error")

	var rerr *Error

	switch e := err.(type) {
	case *Error:
		rerr = e
	case *echo.HTTPError:
		// todo: improve error conversion
		rerr = NewTypeError(e.Code, EchoHttpError, e.Error())
	default:
		rerr = NewTypeError(http.StatusInternalServerError, InternalError, e.Error())
	}

	c.JSON(rerr.Code, rerr)
}
// error.go

package main

import (
	"fmt"
)

const (
	EchoHttpError int = iota
	InternalError
)

type Error struct {
	Code     int    `json:"-"` // optional
	Message  string `json:"message"`
	Internal int    `json:"internal"`
}

func (e *Error) Error() string {
	fmt.Println("Hello error")
	return "error"
}

func NewTypeError(code int, internal int, message string) *Error {
	fmt.Println(internal)
	fmt.Println(message)
	return &Error{
		Code:     code,
		Message:  message,
		Internal: internal,
	}
}

答案2

得分: 2

你应该在参数中插入模型。
并且你应该创建一个与结构体相同的变量response。
如果你在response中显示代码,你应该在error结构体中添加代码。

func ToErrorResponse(err model.Error) *ErrorResponse {
	errorResponse := &ErrorResponse{
		code:    err.Code,
		message: err.Message,
	}
	return errorResponse
}

然后调用函数。

英文:

you should insert model on argument.
and u should make variable response, same with struct.
if u show code on response, u should add code on error struct.

func ToErrorResponse(err model.Error) *ErrorResponse {
errorResponse := &ErrorResponse{
code:       err.Code,
message: err.Message,
}
return errorResponse
}

and call function.

huangapple
  • 本文由 发表于 2022年3月13日 22:11:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/71457570.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定