feat: Add Handler() method and fix SSE closed pipe errors (#24)
* feat: add Handler() method for testing and custom server integration Exposes the underlying http.Handler to enable: - Integration testing with gost-dom/browser for SSE/Datastar testing - Custom server setups (e.g., embedding Via in existing applications) - Standard Go httptest patterns 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Suppress closed pipe errors when SSE connection closes Don't log error when SSE fails to send patches if the connection was already closed. This reduces noise in logs during shutdown and testing, where browsers/clients close connections before server handlers finish. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: joeblew999 <joeblew999@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
19
via.go
19
via.go
@@ -243,6 +243,12 @@ func (v *V) Start() {
|
|||||||
log.Fatalf("[fatal] %v", http.ListenAndServe(v.cfg.ServerAddress, v.mux))
|
log.Fatalf("[fatal] %v", http.ListenAndServe(v.cfg.ServerAddress, v.mux))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handler returns the underlying http.Handler for use with custom servers or testing.
|
||||||
|
// This enables integration with test frameworks like gost-dom/browser for SSE/Datastar testing.
|
||||||
|
func (v *V) Handler() http.Handler {
|
||||||
|
return v.mux
|
||||||
|
}
|
||||||
|
|
||||||
func (v *V) devModePersist(c *Context) {
|
func (v *V) devModePersist(c *Context) {
|
||||||
p := filepath.Join(".via", "devmode", "ctx.json")
|
p := filepath.Join(".via", "devmode", "ctx.json")
|
||||||
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
|
||||||
@@ -413,17 +419,24 @@ func New() *V {
|
|||||||
switch patch.typ {
|
switch patch.typ {
|
||||||
case patchTypeElements:
|
case patchTypeElements:
|
||||||
if err := sse.PatchElements(patch.content); err != nil {
|
if err := sse.PatchElements(patch.content); err != nil {
|
||||||
v.logErr(c, "PatchElements failed: %v", err)
|
// Only log if connection wasn't closed (avoids noise during shutdown/tests)
|
||||||
|
if sse.Context().Err() == nil {
|
||||||
|
v.logErr(c, "PatchElements failed: %v", err)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
case patchTypeSignals:
|
case patchTypeSignals:
|
||||||
if err := sse.PatchSignals([]byte(patch.content)); err != nil {
|
if err := sse.PatchSignals([]byte(patch.content)); err != nil {
|
||||||
v.logErr(c, "PatchSignals failed: %v", err)
|
if sse.Context().Err() == nil {
|
||||||
|
v.logErr(c, "PatchSignals failed: %v", err)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
case patchTypeScript:
|
case patchTypeScript:
|
||||||
if err := sse.ExecuteScript(patch.content, datastar.WithExecuteScriptAutoRemove(true)); err != nil {
|
if err := sse.ExecuteScript(patch.content, datastar.WithExecuteScriptAutoRemove(true)); err != nil {
|
||||||
v.logErr(c, "ExecuteScript failed: %v", err)
|
if sse.Context().Err() == nil {
|
||||||
|
v.logErr(c, "ExecuteScript failed: %v", err)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user