vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Show every run in the runs list
a72e39d5b08fa4285bc78ccd6a6b1b3ca992d823 · Keenan Nemetz · 10d ago · parent 1b1fa7a5
Show every run in the runs list The list still asked each row for Log and LogOID, fields the run no longer has now that logs live in run_logs. html/template stops at the first execution error and keeps the bytes it already wrote, so the page looked complete through the first run and silently dropped the rest. Recent and Get now carry HasLog from the same query, the list links a log only when one exists, and a failed render is a 500 rather than a short page.
server/web/errorpage_test.go +17
| @@ -65,6 +65,23 @@ func TestServerErrorPageIsStyledAndHidesTheDetail(t *testing.T) { | |||
| 65 | 65 | } | |
| 66 | 66 | } | |
| 67 | 67 | ||
| 68 | func TestARenderErrorIsAServerError(t *testing.T) { | ||
| 69 | w := newTestWeb(t) | ||
| 70 | w.Logger = func(string, ...any) {} | ||
| 71 | rw := httptest.NewRecorder() | ||
| 72 | // A template that does not exist fails the way a bad field name does: mid | ||
| 73 | // execution, after html/template has already written whatever came before it. | ||
| 74 | // The reader must get an error page rather than the shortened page. | ||
| 75 | w.render(rw, "no-such-template", nil, http.StatusOK) | ||
| 76 | |||
| 77 | if rw.Code != http.StatusInternalServerError { | ||
| 78 | t.Fatalf("status = %d, want 500", rw.Code) | ||
| 79 | } | ||
| 80 | if got := rw.Header().Get("Content-Type"); !strings.Contains(got, "text/plain") { | ||
| 81 | t.Fatalf("content type = %q, want the plain error body rather than a page", got) | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 68 | 85 | func TestMiddlewareTurnsAPanicIntoTheServerErrorPage(t *testing.T) { | |
| 69 | 86 | w := newTestWeb(t) | |
| 70 | 87 | w.Logger = func(string, ...any) {} | |