Skip to content

Commit

Permalink
Added new error page
Browse files Browse the repository at this point in the history
  • Loading branch information
evg4b committed May 20, 2023
1 parent 017904a commit dc0b088
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 17 deletions.
2 changes: 1 addition & 1 deletion internal/handler/mock/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (m *Middleware) ServeHTTP(writer http.ResponseWriter, request *http.Request
}

if err != nil {
http.Error(writer, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
infrastructure.HTTPError(writer, err)

return
}
Expand Down
7 changes: 3 additions & 4 deletions internal/handler/proxy/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import (
"net/http"
"strings"

"github.com/evg4b/uncors/internal/infrastructure"

"github.com/evg4b/uncors/internal/contracts"
"github.com/evg4b/uncors/internal/helpers"
"github.com/evg4b/uncors/internal/urlreplacer"
"github.com/pterm/pterm"
)

type Handler struct {
Expand All @@ -33,9 +34,7 @@ func NewProxyHandler(options ...HandlerOption) *Handler {

func (m *Handler) ServeHTTP(response http.ResponseWriter, request *http.Request) {
if err := m.handle(response, request); err != nil {
pterm.Error.Printfln("UNCORS error: %v", err)
response.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(response, "UNCORS error:", err.Error())
infrastructure.HTTPError(response, err)
}
}

Expand Down
13 changes: 3 additions & 10 deletions internal/handler/static/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"path"
"strings"

"github.com/evg4b/uncors/internal/infrastructure"

"github.com/evg4b/uncors/internal/contracts"

"github.com/spf13/afero"
Expand All @@ -34,14 +36,6 @@ func NewStaticMiddleware(options ...MiddlewareOption) *Middleware {
return middleware
}

func toHTTPError(err error) (string, int) {
if errors.Is(err, fs.ErrPermission) {
return http.StatusText(http.StatusForbidden), http.StatusForbidden
}

return http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError
}

func (m *Middleware) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
filePath := m.extractFilePath(request)

Expand All @@ -56,8 +50,7 @@ func (m *Middleware) ServeHTTP(writer http.ResponseWriter, request *http.Request
if errors.Is(err, errNorHandled) {
m.next.ServeHTTP(writer, request)
} else {
msg, code := toHTTPError(err)
http.Error(writer, msg, code)
infrastructure.HTTPError(writer, err)
}

return
Expand Down
6 changes: 4 additions & 2 deletions internal/handler/uncors_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ func TestUncorsRequestHandler(t *testing.T) {
hand.ServeHTTP(recorder, request)

assert.Equal(t, http.StatusInternalServerError, recorder.Code)
assert.Contains(t, testutils.ReadBody(t, recorder), "Internal Server Error")
expectedMessage := "filed to opend index file: open /assets/index.php: file does not exist"
assert.Contains(t, testutils.ReadBody(t, recorder), expectedMessage)
})
})

Expand Down Expand Up @@ -282,7 +283,8 @@ func TestUncorsRequestHandler(t *testing.T) {
hand.ServeHTTP(recorder, request)

assert.Equal(t, http.StatusInternalServerError, recorder.Code)
assert.Contains(t, testutils.ReadBody(t, recorder), "Internal Server Error")
expectedMessage := "filed to opent file /unknown.json: open /unknown.json: file does not exist"
assert.Contains(t, testutils.ReadBody(t, recorder), expectedMessage)
})
})
}
Expand Down
44 changes: 44 additions & 0 deletions internal/infrastructure/http_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package infrastructure

import (
"fmt"
"io"
"net/http"

"github.com/go-http-utils/headers"
"github.com/pterm/pterm"
"github.com/pterm/pterm/putils"
"github.com/samber/lo"
)

var style = pterm.Style{}

func HTTPError(writer http.ResponseWriter, err error) {
header := writer.Header()
header.Set(headers.ContentType, "text/plain; charset=utf-8")
header.Set(headers.XContentTypeOptions, "nosniff")

writer.WriteHeader(http.StatusInternalServerError)
message := fmt.Sprintf("%d Error", http.StatusInternalServerError)

writeLine(writer)
writeLine(writer, pageHeader(message))
writeLine(writer)
writeLine(writer, fmt.Sprintf("Occurred error: %s", err))
}

func pageHeader(message string) string {
letters := putils.LettersFromStringWithStyle(message, &style)
text, err := pterm.DefaultBigText.WithLetters(letters).Srender()
if err != nil {
panic(err)
}

return text
}

func writeLine(writer io.Writer, data ...string) {
if _, err := fmt.Fprintln(writer, lo.ToAnySlice(data)...); err != nil {
panic(err)
}
}
40 changes: 40 additions & 0 deletions internal/infrastructure/http_error_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package infrastructure_test

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/go-http-utils/headers"

"github.com/evg4b/uncors/internal/infrastructure"
"github.com/evg4b/uncors/testing/testutils"
"github.com/stretchr/testify/assert"
)

const expectedPage = `
███████ ██████ ██████ ███████ ██████ ██████ ██████ ██████
██ ██ ████ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██
███████ ██ ██ ██ ██ ██ ██ █████ ██████ ██████ ██ ██ ██████
██ ████ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
███████ ██████ ██████ ███████ ██ ██ ██ ██ ██████ ██ ██
Occurred error: net/http: abort Handler
`

func TestHttpError(t *testing.T) {
recorder := httptest.NewRecorder()
infrastructure.HTTPError(recorder, http.ErrAbortHandler)

t.Run("write correct page", func(t *testing.T) {
assert.Equal(t, expectedPage, testutils.ReadBody(t, recorder))
})

t.Run("write correct headers", func(t *testing.T) {
header := recorder.Header()

assert.NotNil(t, header[headers.ContentType])
assert.NotNil(t, header[headers.XContentTypeOptions])
})
}

0 comments on commit dc0b088

Please sign in to comment.