better error handling in c&w

This commit is contained in:
Bora M. Alper 2018-12-24 21:30:07 +03:00
parent 64543d71d7
commit 020b55104f
No known key found for this signature in database
GPG Key ID: 8F1A9504E1BD114D
4 changed files with 38 additions and 42 deletions

View File

@ -8,6 +8,7 @@ package mainline
import (
"encoding/binary"
"fmt"
"github.com/pkg/errors"
"net"
"github.com/anacrolix/missinggo/iter"
@ -251,10 +252,10 @@ func (e *Error) UnmarshalBencode(b []byte) (err error) {
matches := result[0][1:]
if _, err := fmt.Sscanf(string(matches[0]), "%d", &code); err != nil {
return fmt.Errorf("could not parse the error code: %s", err.Error())
return errors.Wrap(err, "could not parse error code")
}
if _, err := fmt.Sscanf(string(matches[1]), "%d", &msgLen); err != nil {
return fmt.Errorf("could not parse the error message length: %s", err.Error())
return errors.Wrap(err, "could not parse error msg length")
}
if len(matches[2]) != msgLen {

View File

@ -2,6 +2,8 @@ package main
import (
"encoding/hex"
"fmt"
"github.com/pkg/errors"
"net/http"
"strings"
"time"
@ -14,73 +16,67 @@ import (
func rootHandler(w http.ResponseWriter, r *http.Request) {
nTorrents, err := database.GetNumberOfTorrents()
if err != nil {
panic(err.Error())
handlerError(errors.Wrap(err, "GetNumberOfTorrents"), w)
return
}
err = templates["homepage"].Execute(w, struct {
_ = templates["homepage"].Execute(w, struct {
NTorrents uint
}{
NTorrents: nTorrents,
})
if err != nil {
panic(err.Error())
}
}
// TODO: we might as well move torrents.html into static...
func torrentsHandler(w http.ResponseWriter, r *http.Request) {
data := mustAsset("templates/torrents.html")
w.Header().Set("Content-Type", "text/html; charset=utf-8")
// Cache static resources for a day
w.Header().Set("Cache-Control", "max-age=86400")
w.Write(data)
_, _ = w.Write(data)
}
func torrentsInfohashHandler(w http.ResponseWriter, r *http.Request) {
infoHash, err := hex.DecodeString(mux.Vars(r)["infohash"])
if err != nil {
panic(err.Error())
handlerError(errors.Wrap(err, "cannot decode infohash"), w)
return
}
torrent, err := database.GetTorrent(infoHash)
if err != nil {
panic(err.Error())
handlerError(errors.Wrap(err, "cannot get torrent"), w)
return
}
if torrent == nil {
w.WriteHeader(404)
w.Write([]byte("torrent not found!"))
respondError(w, http.StatusNotFound, "torrent not found!")
return
}
files, err := database.GetFiles(infoHash)
if err != nil {
panic(err.Error())
handlerError(errors.Wrap(err, "could not get files"), w)
return
}
if files == nil {
w.WriteHeader(500)
w.Write([]byte("files not found what!!!"))
handlerError(fmt.Errorf("could not get files"), w)
return
}
err = templates["torrent"].Execute(w, struct {
_ = templates["torrent"].Execute(w, struct {
T *persistence.TorrentMetadata
F []persistence.File
}{
T: torrent,
F: files,
})
if err != nil {
panic("error while executing template!")
}
}
// TODO: we might as well move statistics.html into static...
func statisticsHandler(w http.ResponseWriter, r *http.Request) {
data := mustAsset("templates/statistics.html")
w.Header().Set("Content-Type", "text/html; charset=utf-8")
// Cache static resources for a day
w.Header().Set("Cache-Control", "max-age=86400")
w.Write(data)
_, _ = w.Write(data)
}
func feedHandler(w http.ResponseWriter, r *http.Request) {
@ -111,32 +107,24 @@ func feedHandler(w http.ResponseWriter, r *http.Request) {
nil,
)
if err != nil {
respondError(w, 400, err.Error())
handlerError(errors.Wrap(err, "query torrent"), w)
return
}
// It is much more convenient to write the XML deceleration manually*, and then process the XML
// template using template/html and send, then to use encoding/xml.
// template using template/html and send, than to use encoding/xml.
//
// *: https://github.com/golang/go/issues/3133
//
// TODO: maybe do it properly, even if it's inconvenient?
_, err = w.Write([]byte(`<?xml version="1.0" encoding="utf-8" standalone="yes"?>`))
if err != nil {
panic(err.Error())
}
err = templates["feed"].Execute(w, struct {
_, _ = w.Write([]byte(`<?xml version="1.0" encoding="utf-8" standalone="yes"?>`))
_ = templates["feed"].Execute(w, struct {
Title string
Torrents []persistence.TorrentMetadata
}{
Title: title,
Torrents: torrents,
})
if err != nil {
panic(err.Error())
}
}
func staticHandler(w http.ResponseWriter, r *http.Request) {
@ -155,5 +143,5 @@ func staticHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", contentType)
// Cache static resources for a day
w.Header().Set("Cache-Control", "max-age=86400")
w.Write(data)
_, _ = w.Write(data)
}

View File

@ -5,9 +5,9 @@ import (
"bytes"
"encoding/hex"
"fmt"
"github.com/pkg/errors"
"html/template"
"io"
"log"
"net/http"
"os"
"os/signal"
@ -156,7 +156,7 @@ func main() {
var err error
database, err = persistence.MakeDatabase(opts.Database, logger)
if err != nil {
panic(err.Error())
zap.L().Fatal("could not access to database", zap.Error(err))
}
decoder.IgnoreUnknownKeys(false)
@ -178,7 +178,8 @@ func respondError(w http.ResponseWriter, statusCode int, format string, a ...int
func mustAsset(name string) []byte {
data, err := Asset(name)
if err != nil {
log.Panicf("Could NOT access the requested resource `%s`: %s (please inform us, this is a BUG!)", name, err.Error())
zap.L().Panic("Could NOT access the requested resource! THIS IS A BUG, PLEASE REPORT",
zap.String("name", name), zap.Error(err))
}
return data
}
@ -250,7 +251,7 @@ func loadCred(cred string) error {
if err == io.EOF {
break
}
return fmt.Errorf("error while reading line %d: %s", lineno, err.Error())
return errors.Wrapf(err, "while reading line %d", lineno)
}
line = line[:len(line)-1] // strip '\n'
@ -316,7 +317,5 @@ func BasicAuth(handler http.HandlerFunc, realm string) http.HandlerFunc {
func authenticate(w http.ResponseWriter, realm string) {
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`)
w.WriteHeader(401)
if _, err := w.Write([]byte("Unauthorised.\n")); err != nil {
panic(err.Error())
}
_, _ = w.Write([]byte("Unauthorised.\n"))
}

8
cmd/magneticow/util.go Normal file
View File

@ -0,0 +1,8 @@
package main
import "net/http"
func handlerError(err error, w http.ResponseWriter) {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(err.Error()))
}