1

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"
}

2 Answers 2

2

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,
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Does the Error() method still remains the same. Its return type should be struct right . Else in middleware we receive only string "error" based on above implementation.
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.