mirror of
https://github.com/filebrowser/filebrowser.git
synced 2024-06-07 23:00:43 +00:00
better error pages
This commit is contained in:
parent
012cd383a0
commit
b57bcb6b0e
2
assets/public/js/app.min.js
vendored
2
assets/public/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
@ -186,7 +186,7 @@ $(document).on('page:browse', function() {
|
||||
|
||||
if (request.status == 200) {
|
||||
$.pjax({
|
||||
url: request.Location,
|
||||
url: response.location,
|
||||
container: '#content'
|
||||
})
|
||||
}
|
||||
|
8
assets/templates/error.tmpl
Normal file
8
assets/templates/error.tmpl
Normal file
@ -0,0 +1,8 @@
|
||||
{{ define "content" }}
|
||||
<main role="main" class="container browse error">
|
||||
<h1>{{ .Title }}</h1>
|
||||
<code>{{ .Message }}</code>
|
||||
|
||||
<p><strong>If this error persists contact us on <a href="https://gitter.im/hacdias/caddy-hugo">Gitter chat</a> or open an issue at <a href="https://github.com/hacdias/caddy-hugo/issues/new">GitHub</a>.</strong></p>
|
||||
</main>
|
||||
{{ end }}
|
5
hugo.go
5
hugo.go
@ -18,6 +18,7 @@ import (
|
||||
"github.com/hacdias/caddy-hugo/routes/assets"
|
||||
"github.com/hacdias/caddy-hugo/routes/browse"
|
||||
"github.com/hacdias/caddy-hugo/routes/editor"
|
||||
"github.com/hacdias/caddy-hugo/routes/errors"
|
||||
"github.com/hacdias/caddy-hugo/routes/git"
|
||||
"github.com/hacdias/caddy-hugo/tools/commands"
|
||||
"github.com/hacdias/caddy-hugo/tools/hugo"
|
||||
@ -143,6 +144,10 @@ func (h CaddyHugo) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error
|
||||
code, err = git.ServeHTTP(w, r, h.Config)
|
||||
}
|
||||
|
||||
if code != 0 && code != 200 {
|
||||
code, err = errors.ServeHTTP(w, r, code, err)
|
||||
}
|
||||
|
||||
return code, err
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,11 @@ import (
|
||||
|
||||
var conf *config.Config
|
||||
|
||||
type response struct {
|
||||
Message string `json:"message"`
|
||||
Location string `json:"location"`
|
||||
}
|
||||
|
||||
// ServeHTTP is used to serve the content of Browse page using Browse middleware
|
||||
// from Caddy. It handles the requests for DELETE, POST, GET and PUT related to
|
||||
// /browse interface.
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hacdias/caddy-hugo/tools/server"
|
||||
s "github.com/hacdias/caddy-hugo/tools/server"
|
||||
)
|
||||
|
||||
// DELETE handles the delete requests on browse pages
|
||||
@ -31,17 +31,11 @@ func DELETE(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
|
||||
// Check for errors
|
||||
if err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Something went wrong.",
|
||||
}, 500, nil)
|
||||
return s.RespondJSON(w, &response{err.Error(), ""}, http.StatusInternalServerError, err)
|
||||
}
|
||||
} else {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "File not found.",
|
||||
}, 404, nil)
|
||||
return s.RespondJSON(w, &response{"File not found.", ""}, http.StatusNotFound, nil)
|
||||
}
|
||||
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": message,
|
||||
}, 200, nil)
|
||||
return s.RespondJSON(w, &response{message, ""}, http.StatusOK, nil)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/hacdias/caddy-hugo/tools/commands"
|
||||
"github.com/hacdias/caddy-hugo/tools/server"
|
||||
s "github.com/hacdias/caddy-hugo/tools/server"
|
||||
)
|
||||
|
||||
// POST handles the POST method on browse page. It's used to create new files,
|
||||
@ -36,15 +36,11 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// Check if filename and archetype are specified in
|
||||
// the request
|
||||
if _, ok := info["filename"]; !ok {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Filename not specified.",
|
||||
}, 500, nil)
|
||||
return s.RespondJSON(w, &response{"Filename not specified.", ""}, http.StatusBadRequest, nil)
|
||||
}
|
||||
|
||||
if _, ok := info["archetype"]; !ok {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Archtype not specified.",
|
||||
}, 500, nil)
|
||||
return s.RespondJSON(w, &response{"Archtype not specified.", ""}, http.StatusBadRequest, nil)
|
||||
}
|
||||
|
||||
// Sanitize the file name path
|
||||
@ -66,9 +62,7 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
}
|
||||
|
||||
if err := commands.Run(conf.Hugo, args, conf.Path); err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Something went wrong.",
|
||||
}, 500, err)
|
||||
return s.RespondJSON(w, &response{"Something went wrong.", ""}, http.StatusInternalServerError, err)
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
@ -83,26 +77,19 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Something went wrong.",
|
||||
}, 500, err)
|
||||
return s.RespondJSON(w, &response{"Something went wrong.", ""}, http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"location": url,
|
||||
"message": "File created.",
|
||||
}, 200, nil)
|
||||
return s.RespondJSON(w, &response{"File created!", url}, http.StatusOK, nil)
|
||||
}
|
||||
|
||||
func upload(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// Parse the multipart form in the request
|
||||
err := r.ParseMultipartForm(100000)
|
||||
if err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Something went wrong.",
|
||||
}, 500, err)
|
||||
return s.RespondJSON(w, &response{"Something went wrong.", ""}, http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
// For each file header in the multipart form
|
||||
@ -112,29 +99,23 @@ func upload(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// Open the first file
|
||||
var infile multipart.File
|
||||
if infile, err = hdr.Open(); nil != err {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Something went wrong.",
|
||||
}, 500, err)
|
||||
return s.RespondJSON(w, &response{"Something went wrong.", ""}, http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
// Create the file
|
||||
var outfile *os.File
|
||||
if outfile, err = os.Create(conf.Path + r.URL.Path + hdr.Filename); nil != err {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Something went wrong.",
|
||||
}, 500, err)
|
||||
return s.RespondJSON(w, &response{"Something went wrong.", ""}, http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
// Copy the file content
|
||||
if _, err = io.Copy(outfile, infile); nil != err {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Something went wrong.",
|
||||
}, 500, err)
|
||||
return s.RespondJSON(w, &response{"Something went wrong.", ""}, http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
defer outfile.Close()
|
||||
}
|
||||
}
|
||||
|
||||
return server.RespondJSON(w, nil, 200, nil)
|
||||
return s.RespondJSON(w, nil, http.StatusOK, nil)
|
||||
}
|
||||
|
@ -30,9 +30,7 @@ func PUT(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// Check if filename and archetype are specified in
|
||||
// the request
|
||||
if _, ok := info["filename"]; !ok {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Filename not specified.",
|
||||
}, 400, nil)
|
||||
return server.RespondJSON(w, &response{"Filename not specified.", ""}, http.StatusBadRequest, nil)
|
||||
}
|
||||
|
||||
// Sanitize the file name path
|
||||
@ -43,12 +41,8 @@ func PUT(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
|
||||
// Renames the file/folder
|
||||
if err := os.Rename(old, new); err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Something went wrong.",
|
||||
}, 500, err)
|
||||
return server.RespondJSON(w, &response{err.Error(), ""}, http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "File renamed.",
|
||||
}, 200, nil)
|
||||
return server.RespondJSON(w, &response{"File renamed.", ""}, http.StatusOK, nil)
|
||||
}
|
||||
|
@ -37,9 +37,9 @@ func GET(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
|
||||
// Check if the file exists.
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
return http.StatusNotFound, nil
|
||||
return http.StatusNotFound, err
|
||||
} else if os.IsPermission(err) {
|
||||
return http.StatusForbidden, nil
|
||||
return http.StatusForbidden, err
|
||||
} else if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
@ -47,7 +47,7 @@ func GET(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// Open the file and check if there was some error while opening
|
||||
file, err := ioutil.ReadFile(filename)
|
||||
if os.IsPermission(err) {
|
||||
return http.StatusForbidden, nil
|
||||
return http.StatusForbidden, err
|
||||
} else if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
@ -26,6 +26,10 @@ type info struct {
|
||||
Content map[string]interface{}
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// POST handles the POST method on editor page
|
||||
func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// Get the JSON information sent using a buffer
|
||||
@ -34,9 +38,7 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
err := json.Unmarshal(rawBuffer.Bytes(), &data)
|
||||
|
||||
if err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Error decrypting json.",
|
||||
}, http.StatusInternalServerError, err)
|
||||
return server.RespondJSON(w, &response{"Error decrypting json."}, http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
// Initializes the file content to write
|
||||
@ -46,9 +48,7 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
case "frontmatter-only":
|
||||
f, code, err := parseFrontMatterOnlyFile()
|
||||
if err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": err.Error(),
|
||||
}, code, err)
|
||||
return server.RespondJSON(w, &response{err.Error()}, code, err)
|
||||
}
|
||||
|
||||
file = f
|
||||
@ -61,25 +61,19 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
case "complete":
|
||||
f, code, err := parseCompleteFile()
|
||||
if err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": err.Error(),
|
||||
}, code, err)
|
||||
return server.RespondJSON(w, &response{err.Error()}, code, err)
|
||||
}
|
||||
|
||||
file = f
|
||||
default:
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Invalid content type.",
|
||||
}, http.StatusBadRequest, nil)
|
||||
return server.RespondJSON(w, &response{"Invalid content type."}, http.StatusBadRequest, nil)
|
||||
}
|
||||
|
||||
// Write the file
|
||||
err = ioutil.WriteFile(filename, file, 0666)
|
||||
|
||||
if err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": err.Error(),
|
||||
}, http.StatusInternalServerError, err)
|
||||
return server.RespondJSON(w, &response{err.Error()}, http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
if data.Regenerate {
|
||||
|
51
routes/errors/errors.go
Normal file
51
routes/errors/errors.go
Normal file
@ -0,0 +1,51 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"text/template"
|
||||
|
||||
"github.com/hacdias/caddy-hugo/tools/server"
|
||||
"github.com/hacdias/caddy-hugo/tools/templates"
|
||||
"github.com/hacdias/caddy-hugo/tools/variables"
|
||||
)
|
||||
|
||||
type errorInformation struct {
|
||||
Title string `json:"title"`
|
||||
Message string `json:"message"`
|
||||
err error
|
||||
}
|
||||
|
||||
// ServeHTTP is used to serve the content of GIT API.
|
||||
func ServeHTTP(w http.ResponseWriter, r *http.Request, code int, err error) (int, error) {
|
||||
page := new(errorInformation)
|
||||
page.Title = strconv.Itoa(code) + " " + http.StatusText(code)
|
||||
page.err = err
|
||||
|
||||
if err != nil {
|
||||
page.Message = err.Error()
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
functions := template.FuncMap{
|
||||
"Defined": variables.Defined,
|
||||
}
|
||||
|
||||
tpl, err := templates.Get(r, functions, "error")
|
||||
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
err = tpl.Execute(w, page)
|
||||
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
return 0, page.err
|
||||
default:
|
||||
return server.RespondJSON(w, page, code, err)
|
||||
}
|
||||
}
|
@ -7,16 +7,18 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/hacdias/caddy-hugo/tools/server"
|
||||
s "github.com/hacdias/caddy-hugo/tools/server"
|
||||
)
|
||||
|
||||
type postError struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// POST handles the POST method on GIT page which is only an API.
|
||||
func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// Check if git is installed on the computer
|
||||
if _, err := exec.LookPath("git"); err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Git is not installed on your computer.",
|
||||
}, 400, nil)
|
||||
return s.RespondJSON(w, &postError{"Git is not installed on your computer."}, 400, nil)
|
||||
}
|
||||
|
||||
// Get the JSON information sent using a buffer
|
||||
@ -29,9 +31,7 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
|
||||
// Check if command was sent
|
||||
if _, ok := info["command"]; !ok {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Command not specified.",
|
||||
}, 400, nil)
|
||||
return s.RespondJSON(w, &postError{"Command not specified."}, 400, nil)
|
||||
}
|
||||
|
||||
command := info["command"].(string)
|
||||
@ -42,9 +42,7 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": "Command not specified.",
|
||||
}, 400, nil)
|
||||
return s.RespondJSON(w, &postError{"Command not specified."}, 400, nil)
|
||||
}
|
||||
|
||||
cmd := exec.Command("git", args...)
|
||||
@ -52,12 +50,8 @@ func POST(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
if err != nil {
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": err.Error(),
|
||||
}, 500, err)
|
||||
return s.RespondJSON(w, &postError{err.Error()}, 500, err)
|
||||
}
|
||||
|
||||
return server.RespondJSON(w, map[string]string{
|
||||
"message": string(output),
|
||||
}, 200, nil)
|
||||
return s.RespondJSON(w, &postError{string(output)}, 200, nil)
|
||||
}
|
||||
|
@ -2,12 +2,11 @@ package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RespondJSON used to send JSON responses to the web server
|
||||
func RespondJSON(w http.ResponseWriter, message map[string]string, code int, err error) (int, error) {
|
||||
func RespondJSON(w http.ResponseWriter, message interface{}, code int, err error) (int, error) {
|
||||
if message == nil {
|
||||
message = map[string]string{}
|
||||
}
|
||||
@ -18,10 +17,6 @@ func RespondJSON(w http.ResponseWriter, message map[string]string, code int, err
|
||||
return 500, msgErr
|
||||
}
|
||||
|
||||
if code == 500 && err != nil {
|
||||
err = errors.New(message["message"])
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(code)
|
||||
w.Write(msg)
|
||||
|
Loading…
Reference in New Issue
Block a user