Different handling of errors on routes; push towards using middleware
This commit is contained in:
parent
057cdbd927
commit
c0a641247b
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/pterodactyl/wings
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
emperror.dev/errors v0.8.0
|
||||||
github.com/AlecAivazis/survey/v2 v2.1.0
|
github.com/AlecAivazis/survey/v2 v2.1.0
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||||
github.com/Jeffail/gabs/v2 v2.5.1
|
github.com/Jeffail/gabs/v2 v2.5.1
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -1,5 +1,7 @@
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
emperror.dev/errors v0.8.0 h1:4lycVEx0sdJkwDUfQ9pdu6SR0x7rgympt5f4+ok8jDk=
|
||||||
|
emperror.dev/errors v0.8.0/go.mod h1:YcRvLPh626Ubn2xqtoprejnA5nFha+TJ+2vew48kWuE=
|
||||||
github.com/AlecAivazis/survey/v2 v2.1.0 h1:AT4+23hOFopXYZaNGugbk7MWItkz0SfTmH/Hk92KeeE=
|
github.com/AlecAivazis/survey/v2 v2.1.0 h1:AT4+23hOFopXYZaNGugbk7MWItkz0SfTmH/Hk92KeeE=
|
||||||
github.com/AlecAivazis/survey/v2 v2.1.0/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
|
github.com/AlecAivazis/survey/v2 v2.1.0/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||||
|
@ -561,9 +563,13 @@ go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
|
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||||
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"emperror.dev/errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
"github.com/apex/log/handlers/cli"
|
"github.com/apex/log/handlers/cli"
|
||||||
color2 "github.com/fatih/color"
|
color2 "github.com/fatih/color"
|
||||||
"github.com/mattn/go-colorable"
|
"github.com/mattn/go-colorable"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"io"
|
"io"
|
||||||
"math"
|
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -42,10 +41,6 @@ func New(w io.Writer, useColors bool) *Handler {
|
||||||
return &Handler{Writer: colorable.NewNonColorable(w), Padding: 2}
|
return &Handler{Writer: colorable.NewNonColorable(w), Padding: 2}
|
||||||
}
|
}
|
||||||
|
|
||||||
type tracer interface {
|
|
||||||
StackTrace() errors.StackTrace
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleLog implements log.Handler.
|
// HandleLog implements log.Handler.
|
||||||
func (h *Handler) HandleLog(e *log.Entry) error {
|
func (h *Handler) HandleLog(e *log.Entry) error {
|
||||||
color := cli.Colors[e.Level]
|
color := cli.Colors[e.Level]
|
||||||
|
@ -71,15 +66,12 @@ func (h *Handler) HandleLog(e *log.Entry) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err, ok := e.Fields.Get("error").(error); ok {
|
if err, ok := e.Fields.Get("error").(error); ok {
|
||||||
if e, ok := errors.Cause(err).(tracer); ok {
|
// Attach the stacktrace if it is missing at this point, but don't point
|
||||||
st := e.StackTrace()
|
// it specifically to this line since that is irrelevant.
|
||||||
l := math.Min(float64(len(st)), 10)
|
err = errors.WithStackDepthIf(err, 1)
|
||||||
fmt.Fprintf(h.Writer, "\n%s%+v\n\n", boldred.Sprintf("Stacktrace:"), st[0:int(l)])
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(h.Writer, "\n%s\n%+v\n\n", boldred.Sprintf("Stacktrace:"), err)
|
fmt.Fprintf(h.Writer, "\n%s\n%+v\n\n", boldred.Sprintf("Stacktrace:"), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"emperror.dev/errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/pterodactyl/wings/server"
|
"github.com/pterodactyl/wings/server"
|
||||||
"github.com/pterodactyl/wings/server/filesystem"
|
"github.com/pterodactyl/wings/server/filesystem"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -20,6 +20,15 @@ type RequestError struct {
|
||||||
server *server.Server
|
server *server.Server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attaches an error to the gin.Context object for the request and ensures that it
|
||||||
|
// has a proper stacktrace associated with it when doing so.
|
||||||
|
//
|
||||||
|
// If you just call c.Error(err) without using this function you'll likely end up
|
||||||
|
// with an error that has no annotated stack on it.
|
||||||
|
func WithError(c *gin.Context, err error) error {
|
||||||
|
return c.Error(errors.WithStackDepthIf(err, 1))
|
||||||
|
}
|
||||||
|
|
||||||
// Generates a new tracked error, which simply tracks the specific error that
|
// Generates a new tracked error, which simply tracks the specific error that
|
||||||
// is being passed in, and also assigned a UUID to the error so that it can be
|
// is being passed in, and also assigned a UUID to the error so that it can be
|
||||||
// cross referenced in the logs.
|
// cross referenced in the logs.
|
||||||
|
@ -42,9 +51,9 @@ func NewServerError(err error, s *server.Server) *RequestError {
|
||||||
|
|
||||||
func (e *RequestError) logger() *log.Entry {
|
func (e *RequestError) logger() *log.Entry {
|
||||||
if e.server != nil {
|
if e.server != nil {
|
||||||
return e.server.Log().WithField("error_id", e.uuid)
|
return e.server.Log().WithField("error_id", e.uuid).WithField("error", e.err)
|
||||||
}
|
}
|
||||||
return log.WithField("error_id", e.uuid)
|
return log.WithField("error_id", e.uuid).WithField("error", e.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the output message to display to the user in the error.
|
// Sets the output message to display to the user in the error.
|
||||||
|
@ -67,7 +76,7 @@ func (e *RequestError) AbortWithStatus(status int, c *gin.Context) {
|
||||||
// If this error is because the resource does not exist, we likely do not need to log
|
// If this error is because the resource does not exist, we likely do not need to log
|
||||||
// the error anywhere, just return a 404 and move on with our lives.
|
// the error anywhere, just return a 404 and move on with our lives.
|
||||||
if errors.Is(e.err, os.ErrNotExist) {
|
if errors.Is(e.err, os.ErrNotExist) {
|
||||||
e.logger().WithField("error", e.err).Debug("encountered os.IsNotExist error while handling request")
|
e.logger().Debug("encountered os.IsNotExist error while handling request")
|
||||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
||||||
"error": "The requested resource was not found on the system.",
|
"error": "The requested resource was not found on the system.",
|
||||||
})
|
})
|
||||||
|
@ -84,9 +93,9 @@ func (e *RequestError) AbortWithStatus(status int, c *gin.Context) {
|
||||||
|
|
||||||
// Otherwise, log the error to zap, and then report the error back to the user.
|
// Otherwise, log the error to zap, and then report the error back to the user.
|
||||||
if status >= 500 {
|
if status >= 500 {
|
||||||
e.logger().WithField("error", e.err).Error("unexpected error while handling HTTP request")
|
e.logger().Error("unexpected error while handling HTTP request")
|
||||||
} else {
|
} else {
|
||||||
e.logger().WithField("error", e.err).Debug("non-server error encountered while handling HTTP request")
|
e.logger().Debug("non-server error encountered while handling HTTP request")
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.message == "" {
|
if e.message == "" {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"emperror.dev/errors"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/pterodactyl/wings/config"
|
"github.com/pterodactyl/wings/config"
|
||||||
"github.com/pterodactyl/wings/server"
|
"github.com/pterodactyl/wings/server"
|
||||||
"io"
|
"io"
|
||||||
|
|
|
@ -57,15 +57,12 @@ func getServerFileContents(c *gin.Context) {
|
||||||
// Returns the contents of a directory for a server.
|
// Returns the contents of a directory for a server.
|
||||||
func getServerListDirectory(c *gin.Context) {
|
func getServerListDirectory(c *gin.Context) {
|
||||||
s := ExtractServer(c)
|
s := ExtractServer(c)
|
||||||
|
if stats, err := s.Filesystem().ListDirectory(c.Query("directory")); err != nil {
|
||||||
stats, err := s.Filesystem().ListDirectory(c.Query("directory"))
|
WithError(c, err)
|
||||||
if err != nil {
|
} else {
|
||||||
NewServerError(err, s).AbortFilesystemError(c)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, stats)
|
c.JSON(http.StatusOK, stats)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type renameFile struct {
|
type renameFile struct {
|
||||||
To string `json:"to"`
|
To string `json:"to"`
|
||||||
|
|
Loading…
Reference in New Issue
Block a user