Better handler for committed http responses (#734)

This commit is contained in:
Thomas
2026-06-27 01:41:30 +07:00
committed by GitHub
parent ea6e7b7eb4
commit 453bd09173
2 changed files with 27 additions and 29 deletions
+2 -4
View File
@@ -101,9 +101,7 @@ func DownloadZip(ctx *context.Context) error {
ctx.Response().Header().Set("Content-Type", "application/zip")
ctx.Response().Header().Set("Content-Disposition", "attachment; filename="+gist.Identifier()+".zip")
ctx.Response().Header().Set("Content-Length", strconv.Itoa(len(zipFile.Bytes())))
_, err = ctx.Response().Write(zipFile.Bytes())
if err != nil {
return ctx.ErrorRes(500, "Error writing the zip archive", err)
}
_, _ = ctx.Response().Write(zipFile.Bytes())
return nil
}
+25 -25
View File
@@ -93,44 +93,44 @@ func (s *Server) registerMiddlewares() {
}
func (s *Server) errorHandler(err error, ctx echo.Context) {
data, _ := ctx.Request().Context().Value(context.DataKeyStr).(echo.Map)
if data == nil {
data = echo.Map{}
}
var httpErr *context.HTTPError
data := ctx.Request().Context().Value(context.DataKeyStr).(echo.Map)
if errors.As(err, &httpErr) {
acceptJson := strings.Contains(ctx.Request().Header.Get("Accept"), "application/json")
data["error"] = err
if acceptJson || data["err_render"] == "json" {
if err := ctx.JSON(httpErr.Code, httpErr); err != nil {
if errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) {
return
}
log.Fatal().Err(err).Send()
}
} else {
if isClientGone(err) {
return
}
log.Error().Err(err).Send()
httpErr = &context.HTTPError{Message: err.Error(), Code: http.StatusInternalServerError}
data["error"] = httpErr
}
if err := ctx.Render(httpErr.Code, "error", data); err != nil {
if errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) {
return
}
log.Fatal().Err(err).Send()
}
if ctx.Response().Committed {
return
}
if errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) {
return
acceptJson := strings.Contains(ctx.Request().Header.Get("Accept"), "application/json")
var renderErr error
if acceptJson || data["err_render"] == "json" {
renderErr = ctx.JSON(httpErr.Code, httpErr)
} else {
renderErr = ctx.Render(httpErr.Code, "error", data)
}
log.Error().Err(err).Send()
httpErr = &context.HTTPError{Message: err.Error(), Code: http.StatusInternalServerError}
data["error"] = httpErr
if err := ctx.Render(500, "error", data); err != nil {
if errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) {
return
}
log.Fatal().Err(err).Send()
if renderErr != nil && !isClientGone(renderErr) {
log.Error().Err(renderErr).Send()
}
}
func isClientGone(err error) bool {
return errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET)
}
func dataInit(next Handler) Handler {
return func(ctx *context.Context) error {
ctx.SetData("loadStartTime", time.Now())