Improve error handling for HTTP client
This commit is contained in:
parent
16c2dc4a8c
commit
dda9114692
5 changed files with 62 additions and 7 deletions
|
@ -7,21 +7,36 @@ package http
|
|||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/miniflux/miniflux/errors"
|
||||
"github.com/miniflux/miniflux/logger"
|
||||
"github.com/miniflux/miniflux/timer"
|
||||
"github.com/miniflux/miniflux/version"
|
||||
)
|
||||
|
||||
const requestTimeout = 300
|
||||
const maxBodySize = 1024 * 1024 * 15
|
||||
const (
|
||||
// 20 seconds max.
|
||||
requestTimeout = 20
|
||||
|
||||
// 15MB max.
|
||||
maxBodySize = 1024 * 1024 * 15
|
||||
)
|
||||
|
||||
var (
|
||||
errInvalidCertificate = "Invalid SSL certificate (original error: %q)"
|
||||
errTemporaryNetworkOperation = "This website is temporarily unreachable (original error: %q)"
|
||||
errPermanentNetworkOperation = "This website is permanently unreachable (original error: %q)"
|
||||
errRequestTimeout = "Website unreachable, the request timed out after %d seconds"
|
||||
)
|
||||
|
||||
// Client is a HTTP Client :)
|
||||
type Client struct {
|
||||
|
@ -77,6 +92,26 @@ func (c *Client) executeRequest(request *http.Request) (*Response, error) {
|
|||
client := c.buildClient()
|
||||
resp, err := client.Do(request)
|
||||
if err != nil {
|
||||
if uerr, ok := err.(*url.Error); ok {
|
||||
switch uerr.Err.(type) {
|
||||
case x509.CertificateInvalidError, x509.HostnameError:
|
||||
err = errors.NewLocalizedError(errInvalidCertificate, uerr.Err)
|
||||
case *net.OpError:
|
||||
if uerr.Err.(*net.OpError).Temporary() {
|
||||
err = errors.NewLocalizedError(errTemporaryNetworkOperation, uerr.Err)
|
||||
} else {
|
||||
err = errors.NewLocalizedError(errPermanentNetworkOperation, uerr.Err)
|
||||
}
|
||||
case net.Error:
|
||||
nerr := uerr.Err.(net.Error)
|
||||
if nerr.Timeout() {
|
||||
err = errors.NewLocalizedError(errRequestTimeout, requestTimeout)
|
||||
} else if nerr.Temporary() {
|
||||
err = errors.NewLocalizedError(errTemporaryNetworkOperation, nerr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Code generated by go generate; DO NOT EDIT.
|
||||
// 2018-02-08 08:24:29.272801 +0100 CET m=+0.026701596
|
||||
// 2018-02-08 18:11:55.663532104 -0800 PST m=+0.009491930
|
||||
|
||||
package locale
|
||||
|
||||
|
@ -441,7 +441,11 @@ var translations = map[string]string{
|
|||
"Miniflux API": "API de Miniflux",
|
||||
"API Endpoint": "Point de terminaison de l'API",
|
||||
"Your account password": "Le mot de passe de votre compte",
|
||||
"This web page is empty": "Cette page web est vide"
|
||||
"This web page is empty": "Cette page web est vide",
|
||||
"Invalid SSL certificate (original error: %q)": "Certificat SSL invalide (erreur originale : %q)",
|
||||
"This website is temporarily unreachable (original error: %q)": "Ce site web est temporairement injoignable (erreur originale : %q)",
|
||||
"This website is permanently unreachable (original error: %q)": "Ce site web n'est pas joignable de façon permanente (erreur originale : %q)",
|
||||
"Website unreachable, the request timed out after %d seconds": "Site web injoignable, la requête à échouée après %d secondes"
|
||||
}
|
||||
`,
|
||||
}
|
||||
|
@ -449,5 +453,5 @@ var translations = map[string]string{
|
|||
var translationsChecksums = map[string]string{
|
||||
"de_DE": "6528d76d5c78b45db4a137a092953155e81d47a64e91aa2411829e5d946e0e28",
|
||||
"en_US": "6fe95384260941e8a5a3c695a655a932e0a8a6a572c1e45cb2b1ae8baa01b897",
|
||||
"fr_FR": "e1f5604630f7dfffe81718f3647d6d3689ec3c4d9a2c78ed7641704e2b913b74",
|
||||
"fr_FR": "ae61f82ac14bc2c6c6a3c2d38cf1ad8309ac2eef19b0726b2969ac155ccddc14",
|
||||
}
|
||||
|
|
|
@ -210,5 +210,9 @@
|
|||
"Miniflux API": "API de Miniflux",
|
||||
"API Endpoint": "Point de terminaison de l'API",
|
||||
"Your account password": "Le mot de passe de votre compte",
|
||||
"This web page is empty": "Cette page web est vide"
|
||||
"This web page is empty": "Cette page web est vide",
|
||||
"Invalid SSL certificate (original error: %q)": "Certificat SSL invalide (erreur originale : %q)",
|
||||
"This website is temporarily unreachable (original error: %q)": "Ce site web est temporairement injoignable (erreur originale : %q)",
|
||||
"This website is permanently unreachable (original error: %q)": "Ce site web n'est pas joignable de façon permanente (erreur originale : %q)",
|
||||
"Website unreachable, the request timed out after %d seconds": "Site web injoignable, la requête à échouée après %d secondes"
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@ func (h *Handler) CreateFeed(userID, categoryID int64, url string, crawler bool)
|
|||
client := http.NewClient(url)
|
||||
response, err := client.Get()
|
||||
if err != nil {
|
||||
if _, ok := err.(errors.LocalizedError); ok {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errors.NewLocalizedError(errRequestFailed, err)
|
||||
}
|
||||
|
||||
|
@ -120,7 +123,13 @@ func (h *Handler) RefreshFeed(userID, feedID int64) error {
|
|||
client := http.NewClientWithCacheHeaders(originalFeed.FeedURL, originalFeed.EtagHeader, originalFeed.LastModifiedHeader)
|
||||
response, err := client.Get()
|
||||
if err != nil {
|
||||
customErr := errors.NewLocalizedError(errRequestFailed, err)
|
||||
var customErr errors.LocalizedError
|
||||
if lerr, ok := err.(errors.LocalizedError); ok {
|
||||
customErr = lerr
|
||||
} else {
|
||||
customErr = errors.NewLocalizedError(errRequestFailed, err)
|
||||
}
|
||||
|
||||
originalFeed.ParsingErrorCount++
|
||||
originalFeed.ParsingErrorMsg = customErr.Error()
|
||||
h.store.UpdateFeed(originalFeed)
|
||||
|
|
|
@ -33,6 +33,9 @@ func FindSubscriptions(websiteURL string) (Subscriptions, error) {
|
|||
client := http.NewClient(websiteURL)
|
||||
response, err := client.Get()
|
||||
if err != nil {
|
||||
if _, ok := err.(errors.LocalizedError); ok {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errors.NewLocalizedError(errConnectionFailure, err)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue