echo icon indicating copy to clipboard operation
echo copied to clipboard

Not found error conflict with StaticWithConfig middleware

Open marcantoinegodde opened this issue 8 months ago • 2 comments

Hello,

I've encountered a situation which seems to be a bug to me.

In the following code, I set up the static middleware with HTML5 param to true so I can have my SPA embedded. In my API, I could have endpoints that would return legit 404 (id not found in database, whatever..) but when this happens, it conflicts with the static middleware (because of HTML5: true). It would catch the error and return the index.html with a 200 instead of a JSON with a 404 that could be handled by the SPA.

Is this intended? Would you have suggestions? Thanks :)

package main

import (
	"embed"
	"errors"
	"log/slog"
	"net/http"

	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
)

//go:embed all:dist
var ui embed.FS

func main() {
	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Serve static files
	e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
		HTML5:      true,
		Root:       "dist",
		Filesystem: http.FS(ui),
	}))

	// Routes
	api := e.Group("/api")
	api.GET("/test/:id", func(c echo.Context) error {
		id := c.Param("id")
		if id == "3" {
			return echo.NewHTTPError(http.StatusNotFound, "not found")
		}
		return c.String(http.StatusOK, "ID: "+id)
	})

	// Start server
	if err := e.Start(":8080"); err != nil && !errors.Is(err, http.ErrServerClosed) {
		slog.Error("failed to start server", "error", err)
	}
}

marcantoinegodde avatar May 12 '25 09:05 marcantoinegodde

I encounter this today,

I just add a skipper to skip the middleware if url starts with /api, which look like it fixed the issue.

		e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
			Filesystem: http.FS(frontEndFiles),
			HTML5:      true,
			Skipper: func(c echo.Context) bool {
				return strings.HasPrefix(c.Request().URL.Path, "/api")
			},
		}))

ekremparlak avatar May 13 '25 10:05 ekremparlak

Just after posting this issue, I ended up doing the same and indeed, it works perfectly. I am still wondering if this behaviour is intended?

To me, HTM5 setting should only catch 404 errors if we don't have a route match, which is obviously not the case here.

marcantoinegodde avatar May 13 '25 14:05 marcantoinegodde