@@ -415,6 +415,15 @@ func (c *Context) Render(code int, name string, data any) (err error) {
415415 if c .echo .Renderer == nil {
416416 return ErrRendererNotRegistered
417417 }
418+ // as Renderer.Render can fail, and in that case we need to delay sending status code to the client until
419+ // (global) error handler decides the correct status code for the error to be sent to the client, so we need to write
420+ // the rendered template to the buffer first.
421+ //
422+ // html.Template.ExecuteTemplate() documentations writes:
423+ // > If an error occurs executing the template or writing its output,
424+ // > execution stops, but partial results may already have been written to
425+ // > the output writer.
426+
418427 buf := new (bytes.Buffer )
419428 if err = c .echo .Renderer .Render (c , buf , name , data ); err != nil {
420429 return
@@ -455,14 +464,12 @@ func (c *Context) jsonPBlob(code int, callback string, i any) (err error) {
455464func (c * Context ) json (code int , i any , indent string ) error {
456465 c .writeContentType (MIMEApplicationJSON )
457466
458- if r , err := UnwrapResponse (c .response ); err == nil {
459- // *echo.Response can delay sending status code until the first Write is called. As serialization can fail, we should delay
460- // sending the status code to the client until serialization is complete (first Write would be an indication it succeeded)
461- // Unsuccessful serialization error needs to go through the error handler and get a proper status code there.
462- r .Status = code
463- } else {
464- return fmt .Errorf ("json: response does not unwrap to *echo.Response" )
465- }
467+ // as JSONSerializer.Serialize can fail, and in that case we need to delay sending status code to the client until
468+ // (global) error handler decides correct status code for the error to be sent to the client.
469+ // For that we need to use writer that can store the proposed status code until the first Write is called.
470+ resp := c .Response ()
471+ c .SetResponse (& delayedStatusWriter {ResponseWriter : resp , status : code })
472+ defer c .SetResponse (resp )
466473
467474 return c .echo .JSONSerializer .Serialize (c , i , indent )
468475}
0 commit comments