Compare commits

...

6 commits

Author SHA1 Message Date
WJQSERVER
fba6fedfc5
Update context.go
Some checks failed
Go Test / test (push) Has been cancelled
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-30 01:17:59 +08:00
WJQSERVER
d0fa14c3c5
Update context.go
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-03-30 01:17:32 +08:00
wjqserver
45c6d36748 fix(HTMLBuf): return 500 on template error, no content
- Remove fallback to HTML() on template rendering failure
- Return 500 error without writing any content on error
- Only fallback to HTML() when renderer is nil or unsupported type
- Prevents multiple response writes
2026-03-30 01:02:37 +08:00
wjqserver
b4e45610b2 refactor(HTMLBuf): delegate fallback to HTML() method
Reduce code duplication by calling c.HTML() for fallback cases:
- When template rendering fails
- When HTMLRender is not configured
- When HTMLRender is not a *template.Template

This ensures consistent behavior between HTMLBuf and HTML methods.
2026-03-30 00:29:50 +08:00
wjqserver
b09595e745 fix: address PR #73 review feedback
- Remove redundant c.Errorf call in JSONBuf
- Consolidate error wrapping in HTMLBuf to avoid duplicate fmt.Errorf calls
- Keep error handling consistent across all Buf methods
2026-03-29 23:43:29 +08:00
wjqserver
6e33bc48aa fix: simplify error handling in Buf methods
Consolidate error wrapping to avoid redundant fmt.Errorf calls.
Follows PR #73 review feedback.
2026-03-29 18:45:08 +08:00

View file

@ -418,18 +418,19 @@ func (c *Context) JSON(code int, obj any) {
} }
// JSONBuf 先将 JSON 编码到 buffer, 成功后再写入状态码和响应体. // JSONBuf 先将 JSON 编码到 buffer, 成功后再写入状态码和响应体.
// 与 JSON 相比, 编码失败时可以正确返回 500 状态码, 代价是多一次内存分配. // 与 JSON 相比,编码失败时可以正确返回 500 状态码,代价是多一次内存分配.
func (c *Context) JSONBuf(code int, obj any) { func (c *Context) JSONBuf(code int, obj any) {
data, err := json.Marshal(obj) var buf bytes.Buffer
if err != nil { if err := json.MarshalWrite(&buf, obj); err != nil {
c.AddError(fmt.Errorf("failed to marshal JSON: %w", err)) errMsg := fmt.Errorf("failed to marshal JSON: %w", err)
c.Errorf("failed to marshal JSON: %s", err) c.AddError(errMsg)
c.ErrorUseHandle(http.StatusInternalServerError, fmt.Errorf("failed to marshal JSON: %w", err)) c.ErrorUseHandle(http.StatusInternalServerError, errMsg)
return return
} }
c.Writer.Header().Set("Content-Type", "application/json; charset=utf-8") c.Writer.Header().Set("Content-Type", "application/json; charset=utf-8")
c.Writer.WriteHeader(code) c.Writer.WriteHeader(code)
c.Writer.Write(data) c.Writer.Write(buf.Bytes())
} }
// GOB 向响应写入GOB数据 // GOB 向响应写入GOB数据
@ -451,8 +452,9 @@ func (c *Context) GOBBuf(code int, obj any) {
var buf bytes.Buffer var buf bytes.Buffer
encoder := gob.NewEncoder(&buf) encoder := gob.NewEncoder(&buf)
if err := encoder.Encode(obj); err != nil { if err := encoder.Encode(obj); err != nil {
c.AddError(fmt.Errorf("failed to encode GOB: %w", err)) errMsg := fmt.Errorf("failed to encode GOB: %w", err)
c.ErrorUseHandle(http.StatusInternalServerError, fmt.Errorf("failed to encode GOB: %w", err)) c.AddError(errMsg)
c.ErrorUseHandle(http.StatusInternalServerError, errMsg)
return return
} }
c.Writer.Header().Set("Content-Type", "application/octet-stream") c.Writer.Header().Set("Content-Type", "application/octet-stream")
@ -476,15 +478,17 @@ func (c *Context) WANF(code int, obj any) {
// WANFBuf 先将 WANF 编码到 buffer, 成功后再写入状态码和响应体. // WANFBuf 先将 WANF 编码到 buffer, 成功后再写入状态码和响应体.
func (c *Context) WANFBuf(code int, obj any) { func (c *Context) WANFBuf(code int, obj any) {
data, err := wanf.Marshal(obj) var buf bytes.Buffer
if err != nil { encoder := wanf.NewStreamEncoder(&buf)
c.AddError(fmt.Errorf("failed to encode WANF: %w", err)) if err := encoder.Encode(obj); err != nil {
c.ErrorUseHandle(http.StatusInternalServerError, fmt.Errorf("failed to encode WANF: %w", err)) errMsg := fmt.Errorf("failed to encode WANF: %w", err)
c.AddError(errMsg)
c.ErrorUseHandle(http.StatusInternalServerError, errMsg)
return return
} }
c.Writer.Header().Set("Content-Type", "application/vnd.wjqserver.wanf; charset=utf-8") c.Writer.Header().Set("Content-Type", "application/vnd.wjqserver.wanf; charset=utf-8")
c.Writer.WriteHeader(code) c.Writer.WriteHeader(code)
c.Writer.Write(data) c.Writer.Write(buf.Bytes())
} }
// HTML 渲染 HTML 模板 // HTML 渲染 HTML 模板
@ -512,26 +516,33 @@ func (c *Context) HTML(code int, name string, obj any) {
} }
// HTMLBuf 先将 HTML 模板渲染到 buffer, 成功后再写入状态码和响应体. // HTMLBuf 先将 HTML 模板渲染到 buffer, 成功后再写入状态码和响应体.
// 如果模板渲染失败,则返回 500 错误且不写入任何内容.
func (c *Context) HTMLBuf(code int, name string, obj any) { func (c *Context) HTMLBuf(code int, name string, obj any) {
if c.engine != nil && c.engine.HTMLRender != nil { if c.engine == nil || c.engine.HTMLRender == nil {
if tpl, ok := c.engine.HTMLRender.(*template.Template); ok { // 没有渲染器,回退到简单输出
var buf bytes.Buffer c.HTML(code, name, obj)
err := tpl.ExecuteTemplate(&buf, name, obj) return
if err != nil { }
c.AddError(fmt.Errorf("failed to render HTML template '%s': %w", name, err))
c.ErrorUseHandle(http.StatusInternalServerError, fmt.Errorf("failed to render HTML template '%s': %w", name, err)) if tpl, ok := c.engine.HTMLRender.(*template.Template); ok {
return var buf bytes.Buffer
} err := tpl.ExecuteTemplate(&buf, name, obj)
c.Writer.Header().Set("Content-Type", "text/html; charset=utf-8") if err != nil {
c.Writer.WriteHeader(code) // 渲染失败,记录错误并返回 500不写入任何内容
c.Writer.Write(buf.Bytes()) errMsg := fmt.Errorf("failed to render HTML template '%s': %w", name, err)
c.AddError(errMsg)
c.ErrorUseHandle(http.StatusInternalServerError, errMsg)
return return
} }
// 渲染成功,写入响应
c.Writer.Header().Set("Content-Type", "text/html; charset=utf-8")
c.Writer.WriteHeader(code)
c.Writer.Write(buf.Bytes())
return
} }
// 默认简单输出
c.Writer.Header().Set("Content-Type", "text/html; charset=utf-8") // 不支持的渲染器类型,回退到简单输出
c.Writer.WriteHeader(code) c.HTML(code, name, obj)
c.Writer.Write(fmt.Appendf(nil, "<!-- HTML rendered for %s -->\n<pre>%v</pre>", name, obj))
} }
// Redirect 执行 HTTP 重定向 // Redirect 执行 HTTP 重定向