feat: upload audio, get a private Swedish transcript, discuss it (#33, ADR-033) #39

Merged
mathias merged 299 commits from feat/33-audio-upload-transcript into main 2026-10-03 14:13:37 +00:00
Showing only changes of commit d8eea66c4c - Show all commits
+42
View File
@@ -0,0 +1,42 @@
// Package errkind reduces an error to a short kind that is safe to log, store and show.
//
// An error's own text can hold a provider's response body (a gateway that echoes the
// prompt), a file path (ffmpeg names the spool file), or a word from a private
// transcript. None of that may reach a log line, a database column or a page about a
// private recording (ADR-033: "typed, never a provider's string"; ADR-035). Of returns
// only a fixed vocabulary, so it can never carry any.
package errkind
import (
"context"
"errors"
"fmt"
"net"
)
// HTTPStatuser is implemented by errors that are a non-2xx answer from a service.
type HTTPStatuser interface{ HTTPStatus() int }
// Of is the kind of err: "timeout", "canceled", "http_<code>", "network", or "error".
// It is empty for nil.
func Of(err error) string {
if err == nil {
return ""
}
var hs HTTPStatuser
var ne net.Error
switch {
case errors.Is(err, context.DeadlineExceeded):
return "timeout"
case errors.Is(err, context.Canceled):
return "canceled"
case errors.As(err, &hs):
return fmt.Sprintf("http_%d", hs.HTTPStatus())
case errors.As(err, &ne):
if ne.Timeout() {
return "timeout"
}
return "network"
}
return "error"
}