vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
Render the styled error page for every miss and failure
e84a66f5b53c269d8b0c207d0335b537e1646cb3 · Keenan Nemetz · 15d ago · parent f6f4b1db
Render the styled error page for every miss and failure Handler-level 404s now use the same view as the catch-all, including unknown detail resources and download paths. Internal 500s render the shared error layout and log the detail instead of exposing it. A panic before the first byte is recovered into that page; a partial response is left to net/http. Also mark label/assignee triage and inline review comments done in the UI plan, where the slice order was stale.
server/web/auth_handlers.go +5−5
| @@ -243,7 +243,7 @@ func (w *Web) InviteFinish(rw http.ResponseWriter, r *http.Request) { | |||
| 243 | 243 | // refused for a different reason. | |
| 244 | 244 | func (w *Web) RegisterPage(rw http.ResponseWriter, r *http.Request) { | |
| 245 | 245 | if !w.registrationEnabled() { | |
| 246 | http.NotFound(rw, r) | ||
| 246 | w.notFound(rw, r) | ||
| 247 | 247 | return | |
| 248 | 248 | } | |
| 249 | 249 | w.render(rw, "register", struct { | |
| @@ -369,7 +369,7 @@ func (w *Web) AccountPage(rw http.ResponseWriter, r *http.Request) { | |||
| 369 | 369 | } | |
| 370 | 370 | creds, err := w.Ident.Credentials(pr.account.ID) | |
| 371 | 371 | if err != nil { | |
| 372 | http.Error(rw, "cannot read passkeys", http.StatusInternalServerError) | ||
| 372 | w.serverError(rw, r, "cannot read passkeys: "+err.Error()) | ||
| 373 | 373 | return | |
| 374 | 374 | } | |
| 375 | 375 | var sessions []session.Session | |
| @@ -481,18 +481,18 @@ func (w *Web) AddPasskeyFinish(rw http.ResponseWriter, r *http.Request) { | |||
| 481 | 481 | // devAccount at all. | |
| 482 | 482 | func (w *Web) DevLogin(rw http.ResponseWriter, r *http.Request) { | |
| 483 | 483 | if w.devAccount == nil || !isLoopbackRequest(r) { | |
| 484 | http.NotFound(rw, r) | ||
| 484 | w.notFound(rw, r) | ||
| 485 | 485 | return | |
| 486 | 486 | } | |
| 487 | 487 | if w.Sessions == nil { | |
| 488 | http.Error(rw, "sessions are unavailable", http.StatusInternalServerError) | ||
| 488 | w.serverError(rw, r, "sessions are unavailable") | ||
| 489 | 489 | return | |
| 490 | 490 | } | |
| 491 | 491 | // Visiting /dev/login is the explicit way back after a logout opted out. | |
| 492 | 492 | w.clearCookieFor(rw, devOffCookieName, false) | |
| 493 | 493 | sess := w.ensureDevSession() | |
| 494 | 494 | if sess == nil { | |
| 495 | http.Error(rw, "cannot create a development session", http.StatusInternalServerError) | ||
| 495 | w.serverError(rw, r, "cannot create a development session") | ||
| 496 | 496 | return | |
| 497 | 497 | } | |
| 498 | 498 | w.setDevSessionCookie(rw, sess) | |