home: improve error handling

This commit is contained in:
Ainar Garipov 2020-12-24 21:44:36 +03:00
parent 39268c754a
commit 664ef85c6c
1 changed files with 30 additions and 9 deletions

View File

@ -2,12 +2,12 @@ package home
import ( import (
"encoding/json" "encoding/json"
"errors"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings"
"syscall" "syscall"
"time" "time"
@ -20,6 +20,13 @@ type getVersionJSONRequest struct {
RecheckNow bool `json:"recheck_now"` RecheckNow bool `json:"recheck_now"`
} }
// temoraryError is the interface for temporary errors from the Go standard
// library.
type temoraryError interface {
error
Temporary() (ok bool)
}
// Get the latest available version from the Internet // Get the latest available version from the Internet
func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) { func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) {
if Context.disableUpdate { if Context.disableUpdate {
@ -42,15 +49,29 @@ func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) {
var info update.VersionInfo var info update.VersionInfo
for i := 0; i != 3; i++ { for i := 0; i != 3; i++ {
Context.controlLock.Lock() func() {
info, err = Context.updater.GetVersionResponse(req.RecheckNow) Context.controlLock.Lock()
Context.controlLock.Unlock() defer Context.controlLock.Unlock()
if err != nil && strings.HasSuffix(err.Error(), "i/o timeout") {
// This case may happen while we're restarting DNS server info, err = Context.updater.GetVersionResponse(req.RecheckNow)
// https://github.com/AdguardTeam/AdGuardHome/issues/934 }()
time.Sleep(time.Duration(i) * time.Second)
continue if err != nil {
var terr temoraryError
if errors.As(err, &terr) && terr.Temporary() {
// Temporary network error. This case may happen while
// we're restarting our DNS server. Log and sleep for
// some time.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/934.
d := time.Duration(i) * time.Second
log.Info("temp net error: %q; sleeping for %s and retrying", err, d)
time.Sleep(d)
continue
}
} }
break break
} }
if err != nil { if err != nil {