Repository: gobuffalo/buffalo
Pull request #2187 (2021-12-09 19:59:00)

v0.18.2


Patch:
diff --git a/errors.go b/errors.go
index 4bfb667d..f9859541 100644
--- a/errors.go
+++ b/errors.go
@@ -112,14 +112,12 @@ func (a *App) defaultErrorMiddleware(next Handler) Handler {
 		}
 		status := http.StatusInternalServerError
 		// unpack root err and check for HTTPError
-		switch {
-		case errors.Is(err, sql.ErrNoRows):
+		if errors.Is(err, sql.ErrNoRows) {
 			status = http.StatusNotFound
-		default:
-			var h HTTPError
-			if errors.As(err, &h) {
-				status = h.Status
-			}
+		}
+		var h HTTPError
+		if errors.As(err, &h) {
+			status = h.Status
 		}
 		payload := events.Payload{
 			"context": c,
diff --git a/route_info.go b/route_info.go
index 7fa12203..8bb849ce 100644
--- a/route_info.go
+++ b/route_info.go
@@ -84,7 +84,7 @@ func (ri *RouteInfo) BuildPathHelper() RouteHelperFunc {
 			return "", fmt.Errorf("missing parameters for %v: %s", cRoute.Path, err)
 		}
 
-		result := url.Path
+		result := url.String()
 		result = addExtraParamsTo(result, opts)
 
 		return template.HTML(result), nil
diff --git a/route_mappings.go b/route_mappings.go
index 1e860b01..4f42b055 100644
--- a/route_mappings.go
+++ b/route_mappings.go
@@ -84,6 +84,29 @@ func (a *App) Mount(p string, h http.Handler) {
 	a.ANY(path, WrapHandler(http.StripPrefix(prefix, h)))
 }
 
+// Host creates a new "*App" group that matches the domain passed.
+// This is useful for creating groups of end-points for different domains.
+/*
+	a.Host("www.example.com")
+	a.Host("{subdomain}.example.com")
+	a.Host("{subdomain:[a-z]+}.example.com")
+*/
+func (a *App) Host(h string) *App {
+	g := New(a.Options)
+
+	g.router = a.router.Host(h).Subrouter()
+	g.RouteNamer = a.RouteNamer
+	g.Middleware = a.Middleware.clone()
+	g.ErrorHandlers = a.ErrorHandlers
+	g.root = a
+
+	if a.root != nil {
+		g.root = a.root
+	}
+
+	return g
+}
+
 // ServeFiles maps an path to a directory on disk to serve static files.
 // Useful for JavaScript, images, CSS, etc...
 /*
diff --git a/runtime/version.go b/runtime/version.go
index dcec814e..c6eafa10 100644
--- a/runtime/version.go
+++ b/runtime/version.go
@@ -1,4 +1,4 @@
 package runtime
 
 // Version is the current version of the buffalo binary
-var Version = "v0.18.1"
+var Version = "v0.18.2"


Test patch:
diff --git a/route_info_test.go b/route_info_test.go
index 4475c384..b24039cd 100644
--- a/route_info_test.go
+++ b/route_info_test.go
@@ -2,6 +2,7 @@ package buffalo
 
 import (
 	"database/sql"
+	"fmt"
 	"net/http"
 	"testing"
 
@@ -22,6 +23,18 @@ func Test_RouteInfo_ServeHTTP_SQL_Error(t *testing.T) {
 		return sql.ErrNoRows
 	})
 
+	app.GET("/bad-2", func(c Context) error {
+		return sql.ErrTxDone
+	})
+
+	app.GET("/gone-unwrap", func(c Context) error {
+		return c.Error(http.StatusGone, sql.ErrTxDone)
+	})
+
+	app.GET("/gone-wrap", func(c Context) error {
+		return c.Error(http.StatusGone, fmt.Errorf("some error wrapping here: %w", sql.ErrNoRows))
+	})
+
 	w := httptest.New(app)
 
 	res := w.HTML("/good").Get()
@@ -29,4 +42,10 @@ func Test_RouteInfo_ServeHTTP_SQL_Error(t *testing.T) {
 
 	res = w.HTML("/bad").Get()
 	r.Equal(http.StatusNotFound, res.Code)
+
+	res = w.HTML("/gone-wrap").Get()
+	r.Equal(http.StatusGone, res.Code)
+
+	res = w.HTML("/gone-unwrap").Get()
+	r.Equal(http.StatusGone, res.Code)
 }
diff --git a/route_mappings_test.go b/route_mappings_test.go
index 5ab171bb..fe80e288 100644
--- a/route_mappings_test.go
+++ b/route_mappings_test.go
@@ -154,3 +154,60 @@ func Test_App_Routes_Resource(t *testing.T) {
 		}
 	}
 }
+
+func Test_App_Host(t *testing.T) {
+	r := require.New(t)
+
+	a1 := New(Options{})
+	r.Nil(a1.root)
+
+	h1 := a1.Host("www.example.com")
+	h1.GET("/foo", voidHandler)
+
+	routes := h1.Routes()
+	r.Len(routes, 1)
+
+	route := routes[0]
+	r.Equal("GET", route.Method)
+	r.Equal("/foo/", route.Path)
+	r.NotZero(route.HandlerName)
+
+	// With Regular Expressions
+
+	a2 := New(Options{})
+	r.Nil(a1.root)
+
+	h2 := a2.Host("{subdomain}.example.com")
+	h2.GET("/foo", voidHandler)
+	h2.GET("/foo/{id}", voidHandler).Name("fooID")
+
+	rh := h2.RouteHelpers()
+
+	routes = h2.Routes()
+	r.Len(routes, 2)
+
+	r.Equal("GET", routes[0].Method)
+	r.Equal("/foo/", routes[0].Path)
+	r.NotZero(routes[0].HandlerName)
+
+	r.Equal("GET", routes[1].Method)
+	r.Equal("/foo/{id}/", routes[1].Path)
+	r.NotZero(routes[1].HandlerName)
+
+	f, ok := rh["fooPath"]
+	r.True(ok)
+	x, err := f(map[string]interface{}{
+		"subdomain": "test",
+	})
+	r.NoError(err)
+	r.Equal("http://test.example.com/foo/", string(x))
+
+	f, ok = rh["fooIDPath"]
+	r.True(ok)
+	x, err = f(map[string]interface{}{
+		"subdomain": "test",
+		"id":        1,
+	})
+	r.NoError(err)
+	r.Equal("http://test.example.com/foo/1/", string(x))
+}