Description

In summary, ErrorTypeRender does not appear to be used anywhere in the code.

We discovered this issue when we were having marshalling failures in context.JSON(). We tried checking context.Errors for errors with type ErrorTypeRender, and realised that nowhere in the code is that set.

Could open a PR for this but wanted to confirm if it was intended or not, since ErrorTypes are super old. I could not find any thread or issue that would suggest it though.

How to reproduce

package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"

    "github.com/gin-gonic/gin"
)

type ProblemObj struct {
}

func (f *ProblemObj) MarshalJSON() ([]byte, error) {
    return nil, fmt.Errorf("this is an error")
}

func main() {
    c, _ := gin.CreateTestContext(httptest.NewRecorder())
    prob := &ProblemObj{}
    c.JSON(http.StatusOK, prob)
    for _, err := range c.Errors {
        fmt.Println(err.IsType(gin.ErrorTypeRender))
    }
}

Expectations

The test code should print true, since the error was occurred during rendering.

Actual result

The test code prints false.

Environment

  • go version: v1.21.1
  • gin version (or commit ref): v1.9.1 and v1.10.0
  • operating system: Mac AMD64

Comment From: RedCrazyGhost

I checked the relevant functions and submission history. This method is quite old and modifications may have a greater impact. I feel that it is not suitable to modify it directly. It is more appropriate to write a branch function and handle it separately for Render.

Comment From: dukepan2005

@RedCrazyGhost What impact?

I don't see any impact, just update following code:

// Render writes the response headers and calls render.Render to render data.
func (c *Context) Render(code int, r render.Render) {
    c.Status(code)

    if !bodyAllowedForStatus(code) {
        r.WriteContentType(c.Writer)
        c.Writer.WriteHeaderNow()
        return
    }

    if err := r.Render(c.Writer); err != nil {
        // Pushing error to c.Errors
        _ = c.Error(err)
        c.Abort()
    }
}

replace _ = c.Error(err)

with _ = c.Error(err).SetType(ErrorTypeRender)