fix: clearer Club Log / FCC ULS upload-download diagnostics
Club Log: on a failed batch, log the callsign#id of every QSO in it so a per-record rejection (e.g. a field value nginx's WAF blocks with a 403) can actually be located instead of hiding behind "batch FAILED". FCC ULS: catch the maintenance bounce before following it. data.fcc.gov redirects to www.fcc.gov/system-maintenance during maintenance windows, and that page then HTTP/2-stream-errors — which surfaced as a cryptic INTERNAL_ERROR. Detect the redirect and return "try again later".
This commit is contained in:
@@ -7846,7 +7846,15 @@ func (a *App) runManualUpload(svc extsvc.Service, ids []int64, cfg extsvc.Extern
|
||||
if err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
// Name the QSOs in the failing batch so a per-record rejection
|
||||
// (e.g. a field value nginx's WAF blocks with a 403) can actually
|
||||
// be located — otherwise "batch FAILED" hides which contact it is.
|
||||
who := make([]string, 0, len(batch))
|
||||
for _, it := range batch {
|
||||
who = append(who, fmt.Sprintf("%s#%d", it.call, it.id))
|
||||
}
|
||||
emit(fmt.Sprintf("Club Log: batch of %d FAILED: %s", len(batch), msg))
|
||||
applog.Printf("extsvc: Club Log batch FAILED (%s) — QSOs: %s", msg, strings.Join(who, ", "))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
+24
-1
@@ -24,6 +24,7 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
@@ -37,6 +38,10 @@ import (
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
// errFCCMaintenance is raised when the FCC ULS download host bounces us to its
|
||||
// maintenance page instead of serving the file (a frequent, FCC-side event).
|
||||
var errFCCMaintenance = errors.New("fcc uls under maintenance")
|
||||
|
||||
// Default download URLs (overridable in Import for tests).
|
||||
const (
|
||||
fccAmateurURL = "https://data.fcc.gov/download/pub/uls/complete/l_amat.zip"
|
||||
@@ -325,8 +330,26 @@ func download(ctx context.Context, url, dest string, prog func(pct int)) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
// Catch the FCC maintenance bounce BEFORE following it: data.fcc.gov redirects
|
||||
// to www.fcc.gov/system-maintenance during maintenance windows, and that page
|
||||
// then HTTP/2-stream-errors — which surfaced as a cryptic "INTERNAL_ERROR"
|
||||
// instead of a plain "try again later".
|
||||
client := &http.Client{
|
||||
CheckRedirect: func(r *http.Request, via []*http.Request) error {
|
||||
if strings.Contains(r.URL.String(), "system-maintenance") {
|
||||
return errFCCMaintenance
|
||||
}
|
||||
if len(via) >= 10 {
|
||||
return errors.New("stopped after 10 redirects")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
if errors.Is(err, errFCCMaintenance) || strings.Contains(err.Error(), "system-maintenance") {
|
||||
return fmt.Errorf("the FCC ULS download service is under maintenance (fcc.gov redirected to its maintenance page) — please try again later")
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
Reference in New Issue
Block a user