oficina / docs Public

app: fix round 1 -- catalog the error string, drop the Handler assertion

Three review findings on the rastrillo skeleton:

- handlers.go hardcoded "Something went wrong." -- now a docs.error.generic
  catalog key resolved through rastrillo.T, matching every other
  user-visible string in this app. ErrorPage/view.Fail wiring stays
  deferred, as intended.
- App.Handler() returned http.Handler, forcing an unchecked
  .(*http.ServeMux) assertion in main.go. Declared as *http.ServeMux
  directly -- satisfies both the test harness and opts.Mux, matches
  SKILL.md's own App(...) (*http.ServeMux, error) shape, no assertion.
- schema/BootSchema double-wrapped an empty migrate.Set. Collapsed to
  one BootSchema var; Task 2 builds the real shape it needs.
Paul Campbell pushed by paul@keymail.dev 032a355ae08c75af51d7317eb9f4a9de7a7cc06b parent a610a1b
4 files changed, +16 −16
  • cmd/docs/main.go +1 −5
  • internal/docs/app.go +8 −10
  • internal/docs/handlers.go +1 −1
  • internal/docs/render.go +6 −0
diff --git a/cmd/docs/main.go b/cmd/docs/main.go
index bbb7def..02c4427 100644
--- a/cmd/docs/main.go
+++ b/cmd/docs/main.go
@@ -3,7 +3,6 @@ package main
import (
"log/slog"
- "net/http"
"os"
"github.com/carlosframework/rastrillo"
@@ -44,10 +43,7 @@ func main() {
}
defer app.Close()
- // App.Handler() returns http.Handler (the interface the task's test
- // harness requires); Options.Mux wants the concrete *http.ServeMux
- // underneath it, which is exactly what App.Handler() always is.
- opts.Mux = app.Handler().(*http.ServeMux)
+ opts.Mux = app.Handler()
opts.DBPath = ""
opts.Locales = docs.Locales
opts.DefaultLocale = docs.DefaultLocale
diff --git a/internal/docs/app.go b/internal/docs/app.go
index 5711984..054384a 100644
--- a/internal/docs/app.go
+++ b/internal/docs/app.go
@@ -50,14 +50,10 @@ type App struct {
logger *slog.Logger
}
-// schema is this app's own migrations. Empty until Task 2 adds
-// models.go; kept as its own var (rather than inlining into BootSchema)
-// so a later merge — migrate.Merge(sessions.Schema, schema), once auth
-// lands — has somewhere to plug in without renaming this one.
-var schema = migrate.Merge()
-
-// BootSchema is everything New applies at boot, in apply order.
-var BootSchema = migrate.Merge(schema)
+// BootSchema is everything New applies at boot, in apply order. Empty
+// until Task 2 adds models.go; migrate.Merge(sessions.Schema, ...)
+// lands here once auth does.
+var BootSchema = migrate.Merge()
// New opens the database, applies migrations and wires the router. It
// is rastrillo SKILL.md's app.go shape: db.Open for the SQLite handle,
@@ -107,8 +103,10 @@ func New(cfg Config) (*App, error) {
// (cmd/docs/main.go), and — per rastrillo's own doc comment on
// Handler/Serve — exactly what a test harness should exercise directly,
// so httptest hits the real route table rather than a hand-duplicated
-// one.
-func (a *App) Handler() http.Handler { return a.mux }
+// one. *http.ServeMux, not http.Handler: it satisfies both callers
+// without forcing an unchecked type assertion on the main.go side,
+// and matches SKILL.md's own App(...) (*http.ServeMux, error) shape.
+func (a *App) Handler() *http.ServeMux { return a.mux }
// Close releases the database handle. NewForTest registers this as a
// t.Cleanup.
diff --git a/internal/docs/handlers.go b/internal/docs/handlers.go
index 1c6856d..b491dfe 100644
--- a/internal/docs/handlers.go
+++ b/internal/docs/handlers.go
@@ -37,6 +37,6 @@ func (h *handlers) home(w http.ResponseWriter, r *http.Request) {
}
if err := h.render.page(w, r, "home", data); err != nil {
h.logger.Error("docs: render home", "err", err)
- http.Error(w, "Something went wrong.", http.StatusInternalServerError)
+ http.Error(w, rastrillo.T(r, "docs.error.generic"), http.StatusInternalServerError)
}
}
diff --git a/internal/docs/render.go b/internal/docs/render.go
index c87f39e..7e85bed 100644
--- a/internal/docs/render.go
+++ b/internal/docs/render.go
@@ -31,6 +31,12 @@ var Catalog = rastrillo.Catalog{
"docs.home.body": "This is the app's first screen: routed, and rendered " +
"through rastrillo's shell. Documents, and a way to sign in, land in " +
"the tasks that follow.",
+
+ // docs.error.generic is the one fallback error string this task
+ // has: a render failure with nowhere styled to land yet (SKILL.md
+ // §7's view.Fail/ErrorPage wiring is later work). Still a catalog
+ // key, never a literal, even though it is plain text today.
+ "docs.error.generic": "Something went wrong.",
}
// Locales and DefaultLocale declare this app's locale set for