Log every webhook request, not just dispatch failures
Some checks failed
CI / test (push) Has been cancelled

The handler was silent on success, unauthorized signatures, and unhandled
events, making it impossible to tell from server logs alone whether a
delivery even arrived. Now every request logs its event type and resulting
status code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
awayatan 2026-07-27 00:06:43 +09:00
parent e433aa3538
commit e95794680b

View file

@ -7,6 +7,7 @@ import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
@ -30,50 +31,57 @@ func NewHandler(secret string, dispatcher Dispatcher) *Handler {
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
event := firstHeader(r, "X-Forgejo-Event", "X-Gitea-Event")
status, err := h.handle(w, r, event)
if err != nil {
log.Printf("yaju-keisatsu: %s event -> %d: %v", event, status, err)
} else {
log.Printf("yaju-keisatsu: %s event -> %d", event, status)
}
if status != http.StatusNoContent {
http.Error(w, http.StatusText(status), status)
return
}
w.WriteHeader(status)
}
func (h *Handler) handle(w http.ResponseWriter, r *http.Request, event string) (int, error) {
if r.Method != http.MethodPost {
return http.StatusMethodNotAllowed, nil
}
body, err := io.ReadAll(io.LimitReader(r.Body, 10<<20)) // 10MiB cap
if err != nil {
http.Error(w, "read body", http.StatusBadRequest)
return
return http.StatusBadRequest, fmt.Errorf("read body: %w", err)
}
if !h.validSignature(r, body) {
http.Error(w, "invalid signature", http.StatusUnauthorized)
return
return http.StatusUnauthorized, fmt.Errorf("invalid signature")
}
event := firstHeader(r, "X-Forgejo-Event", "X-Gitea-Event")
var dispatchErr error
switch event {
case "issue_comment":
var p forgejo.IssueCommentPayload
if err := json.Unmarshal(body, &p); err != nil {
http.Error(w, "decode payload", http.StatusBadRequest)
return
return http.StatusBadRequest, fmt.Errorf("decode payload: %w", err)
}
if err := h.dispatcher.HandleIssueComment(p); err != nil {
return http.StatusInternalServerError, err
}
dispatchErr = h.dispatcher.HandleIssueComment(p)
case "push":
var p forgejo.PushPayload
if err := json.Unmarshal(body, &p); err != nil {
http.Error(w, "decode payload", http.StatusBadRequest)
return
return http.StatusBadRequest, fmt.Errorf("decode payload: %w", err)
}
if err := h.dispatcher.HandlePush(p); err != nil {
return http.StatusInternalServerError, err
}
dispatchErr = h.dispatcher.HandlePush(p)
default:
// Unhandled event types are not an error — the webhook may be
// subscribed to more events than this bot reacts to.
}
if dispatchErr != nil {
log.Printf("yaju-keisatsu: handling %s event: %v", event, dispatchErr)
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
return http.StatusNoContent, nil
}
// validSignature checks X-Forgejo-Signature (falling back to