diff --git a/context.go b/context.go
index 3885301..4bf8144 100644
--- a/context.go
+++ b/context.go
@@ -78,32 +78,34 @@ func (c *Context) QueryParams() url.Values {
return c.request.URL.Query()
}
+// mustWrite writes raw bytes to the response.
+func (c *Context) mustWrite(blob []byte) {
+ if _, err := c.Response().Write(blob); err != nil {
+ panic(err)
+ }
+}
+
// JSON sends JSON response with the given status code.
-//
-// Returns an error if an error happened during sending response otherwise returns nil.
-func (c *Context) JSON(code int, obj any) error {
+func (c *Context) JSON(code int, obj any) {
c.writeContentType("application/json")
c.response.WriteHeader(code)
- return c.kid.jsonSerializer.Write(c.Response(), obj, "")
+ c.kid.jsonSerializer.Write(c.Response(), obj, "")
}
// JSONIndent sends JSON response with the given status code.
// Sends response with the given indent.
-//
-// Returns an error if an error happened during sending response otherwise returns nil.
-func (c *Context) JSONIndent(code int, obj any, indent string) error {
+func (c *Context) JSONIndent(code int, obj any, indent string) {
c.writeContentType("application/json")
c.response.WriteHeader(code)
- return c.kid.jsonSerializer.Write(c.Response(), obj, indent)
+ c.kid.jsonSerializer.Write(c.Response(), obj, indent)
}
// JSONByte sends JSON response with the given status code.
// Writes JSON blob untouched to response.
-func (c *Context) JSONByte(code int, blob []byte) error {
+func (c *Context) JSONByte(code int, blob []byte) {
c.writeContentType("application/json")
c.response.WriteHeader(code)
- _, err := c.Response().Write(blob)
- return err
+ c.mustWrite(blob)
}
// ReadJSON reads request's body as JSON and stores it in the given object.
@@ -115,29 +117,26 @@ func (c *Context) ReadJSON(out any) error {
// XML sends XML response with the given status code.
//
// Returns an error if an error happened during sending response otherwise returns nil.
-func (c *Context) XML(code int, obj any) error {
+func (c *Context) XML(code int, obj any) {
c.writeContentType("application/xml")
c.response.WriteHeader(code)
- return c.kid.xmlSerializer.Write(c.Response(), obj, "")
+ c.kid.xmlSerializer.Write(c.Response(), obj, "")
}
// XMLIndent sends XML response with the given status code.
// Sends response with the given indent.
-//
-// Returns an error if an error happened during sending response otherwise returns nil.
-func (c *Context) XMLIndent(code int, obj any, indent string) error {
+func (c *Context) XMLIndent(code int, obj any, indent string) {
c.writeContentType("application/xml")
c.response.WriteHeader(code)
- return c.kid.xmlSerializer.Write(c.Response(), obj, indent)
+ c.kid.xmlSerializer.Write(c.Response(), obj, indent)
}
// XMLByte sends XML response with the given status code.
// Writes JSON blob untouched to response.
-func (c *Context) XMLByte(code int, blob []byte) error {
+func (c *Context) XMLByte(code int, blob []byte) {
c.writeContentType("application/xml")
c.response.WriteHeader(code)
- _, err := c.Response().Write(blob)
- return err
+ c.mustWrite(blob)
}
// ReadXML reads request's body as XML and stores it in the given object.
@@ -150,22 +149,17 @@ func (c *Context) ReadXML(out any) error {
//
// tpl must be a relative path to templates root directory.
// Defaults to "templates/".
-//
-// Returns an error if an error happened during sending response otherwise returns nil.
-func (c *Context) HTML(code int, tpl string, data any) error {
+func (c *Context) HTML(code int, tpl string, data any) {
c.writeContentType("text/html")
c.response.WriteHeader(code)
- return c.kid.htmlRenderer.RenderHTML(c.Response(), tpl, data)
+ c.kid.htmlRenderer.RenderHTML(c.Response(), tpl, data)
}
// HTMLString sends bare string as HTML response with the given status code.
-//
-// Returns an error if an error happened during sending response otherwise returns nil.
-func (c *Context) HTMLString(code int, tpl string) error {
+func (c *Context) HTMLString(code int, tpl string) {
c.writeContentType("text/html")
c.response.WriteHeader(code)
- _, err := c.Response().Write([]byte(tpl))
- return err
+ c.mustWrite([]byte(tpl))
}
// NoContent returns an empty response with the given status code.
diff --git a/context_test.go b/context_test.go
index 4448b44..db20e5c 100644
--- a/context_test.go
+++ b/context_test.go
@@ -3,6 +3,7 @@ package kid
import (
"encoding/json"
"encoding/xml"
+ "errors"
"fmt"
"net/http"
"net/http/httptest"
@@ -11,11 +12,18 @@ import (
"strings"
"testing"
- "github.com/mojixcoder/kid/errors"
htmlrenderer "github.com/mojixcoder/kid/html_renderer"
"github.com/stretchr/testify/assert"
)
+type errWriter struct {
+ *httptest.ResponseRecorder
+}
+
+func (errWriter) Write(blob []byte) (int, error) {
+ return 0, errors.New("new err")
+}
+
type person struct {
Name string `json:"name" xml:"name"`
Age int `json:"age" xml:"age"`
@@ -238,11 +246,26 @@ func TestContext_ReadJSON(t *testing.T) {
ctx.reset(req, res)
var p2 person
- httpErr := ctx.ReadJSON(&p2).(*errors.HTTPError)
+ err = ctx.ReadJSON(&p2)
+
+ assert.Error(t, err)
+}
+
+func TestContext_mustWrite(t *testing.T) {
+ ctx := newContext(New())
+
+ res := httptest.NewRecorder()
+ ctx.reset(nil, res)
+
+ ctx.mustWrite([]byte("byte"))
+
+ assert.Equal(t, "byte", res.Body.String())
+
+ ctx.reset(nil, errWriter{res})
- assert.Error(t, httpErr)
- assert.Error(t, httpErr.Err)
- assert.Equal(t, http.StatusBadRequest, httpErr.Code)
+ assert.Panics(t, func() {
+ ctx.mustWrite([]byte("byte"))
+ })
}
func TestContext_JSON(t *testing.T) {
@@ -253,9 +276,8 @@ func TestContext_JSON(t *testing.T) {
ctx.reset(nil, res)
p := person{Name: "foo", Age: 1999}
- err := ctx.JSON(http.StatusCreated, &p)
+ ctx.JSON(http.StatusCreated, &p)
- assert.NoError(t, err)
assert.Equal(t, http.StatusCreated, res.Code)
assert.Equal(t, "application/json", res.Header().Get("Content-Type"))
assert.Equal(t, "{\"name\":\"foo\",\"age\":1999}\n", res.Body.String())
@@ -264,11 +286,9 @@ func TestContext_JSON(t *testing.T) {
ctx.reset(nil, res)
- httpErr := ctx.JSON(http.StatusCreated, make(chan bool)).(*errors.HTTPError)
-
- assert.Error(t, httpErr)
- assert.Error(t, httpErr.Err)
- assert.Equal(t, http.StatusInternalServerError, httpErr.Code)
+ assert.Panics(t, func() {
+ ctx.JSON(http.StatusCreated, make(chan bool))
+ })
}
func TestContext_JSONIndent(t *testing.T) {
@@ -279,9 +299,8 @@ func TestContext_JSONIndent(t *testing.T) {
ctx.reset(nil, res)
p := person{Name: "foo", Age: 1999}
- err := ctx.JSONIndent(http.StatusCreated, &p, " ")
+ ctx.JSONIndent(http.StatusCreated, &p, " ")
- assert.NoError(t, err)
assert.Equal(t, http.StatusCreated, res.Code)
assert.Equal(t, "application/json", res.Header().Get("Content-Type"))
assert.Equal(t, "{\n \"name\": \"foo\",\n \"age\": 1999\n}\n", res.Body.String())
@@ -290,11 +309,9 @@ func TestContext_JSONIndent(t *testing.T) {
ctx.reset(nil, res)
- httpErr := ctx.JSONIndent(http.StatusCreated, make(chan bool), " ").(*errors.HTTPError)
-
- assert.Error(t, httpErr)
- assert.Error(t, httpErr.Err)
- assert.Equal(t, http.StatusInternalServerError, httpErr.Code)
+ assert.Panics(t, func() {
+ ctx.JSONIndent(http.StatusCreated, make(chan bool), " ")
+ })
}
func TestContext_JSONByte(t *testing.T) {
@@ -309,9 +326,8 @@ func TestContext_JSONByte(t *testing.T) {
blob, err := json.Marshal(p)
assert.NoError(t, err)
- err = ctx.JSONByte(http.StatusOK, blob)
+ ctx.JSONByte(http.StatusOK, blob)
- assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.Code)
assert.Equal(t, "application/json", res.Header().Get("Content-Type"))
assert.Equal(t, "{\"name\":\"foo\",\"age\":1999}", res.Body.String())
@@ -335,11 +351,9 @@ func TestContext_ReadXML(t *testing.T) {
ctx.reset(req, nil)
var p2 person
- httpErr := ctx.ReadXML(&p2).(*errors.HTTPError)
+ err = ctx.ReadXML(&p2)
- assert.Error(t, httpErr)
- assert.Error(t, httpErr.Err)
- assert.Equal(t, http.StatusBadRequest, httpErr.Code)
+ assert.Error(t, err)
}
func TestContext_XML(t *testing.T) {
@@ -350,9 +364,8 @@ func TestContext_XML(t *testing.T) {
ctx.reset(nil, res)
p := person{Name: "foo", Age: 1999}
- err := ctx.XML(http.StatusCreated, &p)
+ ctx.XML(http.StatusCreated, &p)
- assert.NoError(t, err)
assert.Equal(t, http.StatusCreated, res.Code)
assert.Equal(t, "application/xml", res.Header().Get("Content-Type"))
assert.Equal(t, "
Hello
") + ctx.HTMLString(http.StatusAccepted, "Hello
") - assert.NoError(t, err) assert.Equal(t, http.StatusAccepted, res.Code) assert.Equal(t, "Hello
", res.Body.String()) assert.Equal(t, "text/html", res.Header().Get("Content-Type")) - } diff --git a/errors/errors.go b/errors/errors.go deleted file mode 100644 index 0cb9dd9..0000000 --- a/errors/errors.go +++ /dev/null @@ -1,54 +0,0 @@ -// Package errors implements error interface. -// -// HTTPError has first class support in Kid and is used for returning proper responses when an error happens. -package errors - -import ( - "fmt" - "net/http" -) - -// HTTPError is the struct for returning HTTP errors. -// -// Can be used by Kid's default error handler. -type HTTPError struct { - Code int `json:"-"` - Message any `json:"message"` - Err error `json:"-"` -} - -// Verifying interface compliance. -var _ error = (*HTTPError)(nil) - -// Error implements the error interface and returns error as string. -func (e *HTTPError) Error() string { - if e.Err == nil { - return fmt.Sprintf(`{"code": %d, "message": %q}`, e.Code, e.Message) - } - return fmt.Sprintf(`{"code": %d, "message": %q, "error": %q}`, e.Code, e.Message, e.Err) -} - -// Unwrap implements the errors.Unwrap interface. -func (e *HTTPError) Unwrap() error { - return e.Err -} - -// WithError sets the internal error of HTTP error. -func (e *HTTPError) WithError(err error) *HTTPError { - e.Err = err - return e -} - -// WithMessage sets the error message. -// -// This message will be sent in response in Kid's default error handler. So it should of a type which can be converted to JSON. -func (e *HTTPError) WithMessage(message any) *HTTPError { - e.Message = message - return e -} - -// NewHTTPError returns a new HTTP error. -func NewHTTPError(code int) *HTTPError { - err := HTTPError{Code: code, Message: http.StatusText(code)} - return &err -} diff --git a/errors/errors_test.go b/errors/errors_test.go deleted file mode 100644 index 51aaf95..0000000 --- a/errors/errors_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package errors - -import ( - "errors" - "fmt" - "net/http" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestNewHTTPError(t *testing.T) { - err := NewHTTPError(http.StatusCreated) - - assert.Error(t, err) - assert.Equal(t, http.StatusCreated, err.Code) - assert.Equal(t, http.StatusText(http.StatusCreated), err.Message) - assert.Nil(t, err.Err) -} - -func TestHTTPError_WithMessage(t *testing.T) { - err := NewHTTPError(http.StatusOK).WithMessage("new message") - - assert.Equal(t, http.StatusOK, err.Code) - assert.Equal(t, "new message", err.Message) - assert.Nil(t, err.Err) -} - -func TestHTTPError_WithError(t *testing.T) { - someErr := errors.New("some error") - err := NewHTTPError(http.StatusOK).WithError(someErr) - - assert.Equal(t, http.StatusOK, err.Code) - assert.Equal(t, http.StatusText(http.StatusOK), err.Message) - assert.ErrorIs(t, err.Err, someErr) -} - -func TestHTTPError_Error(t *testing.T) { - err := NewHTTPError(http.StatusOK) - - assert.Equal(t, `{"code": 200, "message": "OK"}`, err.Error()) - - err.WithMessage("something went wrong").WithError(errors.New("some error")) - - assert.Equal(t, `{"code": 200, "message": "something went wrong", "error": "some error"}`, err.Error()) -} - -func TestHTTPError_Unwrap(t *testing.T) { - someErr := errors.New("some error") - err := NewHTTPError(http.StatusForbidden).WithError(someErr) - - newErr := fmt.Errorf("some new error: %w", err) - - unwrapedErr := errors.Unwrap(newErr) - assert.ErrorIs(t, unwrapedErr, err) - - unwrapedErr = errors.Unwrap(unwrapedErr) - assert.ErrorIs(t, unwrapedErr, someErr) - - err = NewHTTPError(http.StatusForbidden) - assert.NoError(t, errors.Unwrap(err)) -} diff --git a/html_renderer/html.go b/html_renderer/html.go index d99c79d..0017bba 100644 --- a/html_renderer/html.go +++ b/html_renderer/html.go @@ -3,14 +3,11 @@ package htmlrenderer import ( "errors" - "fmt" "html/template" "io/fs" "net/http" "path/filepath" "strings" - - kiderrors "github.com/mojixcoder/kid/errors" ) var ( @@ -73,18 +70,17 @@ func (r *defaultHTMLRenderer) AddFunc(name string, f any) { } // RenderHTML implements Kid's HTML renderer. -func (r *defaultHTMLRenderer) RenderHTML(res http.ResponseWriter, path string, data any) error { +func (r *defaultHTMLRenderer) RenderHTML(res http.ResponseWriter, path string, data any) { if err := r.loadTemplates(); err != nil { - return newInternalServerHTTPError(err, err.Error()) + panic(err) } if tpl, ok := r.templates[path]; !ok { - return newInternalServerHTTPError(ErrTemplateNotFound, fmt.Sprintf("template %s not found", path)) + panic(ErrTemplateNotFound) } else { if err := tpl.Execute(res, data); err != nil { - return newInternalServerHTTPError(err, err.Error()) + panic(err) } - return nil } } @@ -126,7 +122,7 @@ func (r *defaultHTMLRenderer) loadTemplates() error { templateFiles, layoutFiles, err := r.getTemplateAndLayoutFiles() if err != nil { - return newInternalServerHTTPError(err, err.Error()) + return err } for _, templateFile := range templateFiles { @@ -168,8 +164,3 @@ func getFilesToParse(templatePath string, layouts []string) []string { files = append(files, layouts...) return files } - -// newInternalServerHTTPError returns a new HTTP error. -func newInternalServerHTTPError(err error, msg any) error { - return kiderrors.NewHTTPError(http.StatusInternalServerError).WithError(err).WithMessage(msg) -} diff --git a/html_renderer/html_test.go b/html_renderer/html_test.go index 580a5f6..a50bfdc 100644 --- a/html_renderer/html_test.go +++ b/html_renderer/html_test.go @@ -3,12 +3,10 @@ package htmlrenderer import ( "fmt" "html/template" - "net/http" "net/http/httptest" "path/filepath" "testing" - "github.com/mojixcoder/kid/errors" "github.com/stretchr/testify/assert" ) @@ -90,12 +88,9 @@ func TestDefaultHTMLRenderer_loadTemplates(t *testing.T) { htmlRenderer := newTestHTMLRenderer() htmlRenderer.rootDir = "invalid_path" - httpErr := htmlRenderer.loadTemplates().(*errors.HTTPError) + err := htmlRenderer.loadTemplates() - assert.Error(t, httpErr) - assert.Error(t, httpErr.Err) - assert.Equal(t, httpErr.Err.Error(), httpErr.Message) - assert.Equal(t, http.StatusInternalServerError, httpErr.Code) + assert.Error(t, err) assert.False(t, htmlRenderer.isInitialized) htmlRenderer = newTestHTMLRenderer() @@ -103,7 +98,7 @@ func TestDefaultHTMLRenderer_loadTemplates(t *testing.T) { return "Hello " + name }) - err := htmlRenderer.loadTemplates() + err = htmlRenderer.loadTemplates() assert.NoError(t, err) assert.True(t, htmlRenderer.isInitialized) @@ -162,26 +157,23 @@ func TestDefaultHTMLRenderer_RenderHTML(t *testing.T) { res := httptest.NewRecorder() - err := htmlRenderer.RenderHTML(res, "index.html", nil) - assert.Error(t, err) + assert.Panics(t, func() { + htmlRenderer.RenderHTML(res, "index.html", nil) + }) htmlRenderer = newTestHTMLRenderer() htmlRenderer.AddFunc("greet", func(name string) string { return "Hello " + name }) - httpErr := htmlRenderer.RenderHTML(res, "doesn't_exists.html", nil).(*errors.HTTPError) - - assert.Error(t, httpErr) - assert.ErrorIs(t, ErrTemplateNotFound, httpErr.Err) - assert.Equal(t, "template doesn't_exists.html not found", httpErr.Message) - assert.Equal(t, http.StatusInternalServerError, httpErr.Code) + assert.PanicsWithError(t, ErrTemplateNotFound.Error(), func() { + htmlRenderer.RenderHTML(res, "doesn't_exists.html", nil) + }) newline := getNewLineStr() res = httptest.NewRecorder() - err = htmlRenderer.RenderHTML(res, "index.html", nil) - assert.NoError(t, err) + htmlRenderer.RenderHTML(res, "index.html", nil) assert.Equal( t, fmt.Sprintf("%s%scontent
%s%s", newline, newline, newline, newline), @@ -189,28 +181,16 @@ func TestDefaultHTMLRenderer_RenderHTML(t *testing.T) { ) res = httptest.NewRecorder() - err = htmlRenderer.RenderHTML(res, "pages/page.html", map[string]string{"key": "page contents"}) - assert.NoError(t, err) + htmlRenderer.RenderHTML(res, "pages/page.html", map[string]string{"key": "page contents"}) assert.Equal(t, fmt.Sprintf("%s%spage contents
%s%s", newline, newline, newline, newline), res.Body.String(), ) res = httptest.NewRecorder() - err = htmlRenderer.RenderHTML(res, "pages/page2.html", nil) - assert.NoError(t, err) + htmlRenderer.RenderHTML(res, "pages/page2.html", nil) assert.Equal(t, fmt.Sprintf("%s%sHello Tom
%s%s", newline, newline, newline, newline), res.Body.String(), ) } - -func TestNewInternalServerHTTPError(t *testing.T) { - err := errors.NewHTTPError(http.StatusBadRequest) - httpErr := newInternalServerHTTPError(err, err.Error()).(*errors.HTTPError) - - assert.Error(t, httpErr) - assert.ErrorIs(t, httpErr.Err, err) - assert.Equal(t, http.StatusInternalServerError, httpErr.Code) - assert.Equal(t, err.Error(), httpErr.Message) -} diff --git a/html_renderer/renderer.go b/html_renderer/renderer.go index 66aa78b..caf8d76 100644 --- a/html_renderer/renderer.go +++ b/html_renderer/renderer.go @@ -5,5 +5,5 @@ import "net/http" // HTMLRenderer is the interface for rendering type HTMLRenderer interface { // RenderHTML renders html template - RenderHTML(res http.ResponseWriter, path string, data any) error + RenderHTML(res http.ResponseWriter, path string, data any) } diff --git a/options_test.go b/options_test.go index 5462330..d3d4469 100644 --- a/options_test.go +++ b/options_test.go @@ -9,13 +9,9 @@ import ( type mockEverything struct{} -func (*mockEverything) RenderHTML(res http.ResponseWriter, path string, data any) error { - return nil -} +func (*mockEverything) RenderHTML(res http.ResponseWriter, path string, data any) {} -func (*mockEverything) Write(w http.ResponseWriter, in any, indent string) error { - return nil -} +func (*mockEverything) Write(w http.ResponseWriter, in any, indent string) {} func (*mockEverything) Read(req *http.Request, out any) error { return nil diff --git a/serializer/json.go b/serializer/json.go index d8c27dc..07e332e 100644 --- a/serializer/json.go +++ b/serializer/json.go @@ -18,24 +18,22 @@ func NewJSONSerializer() Serializer { } // Marshal writes the given object as JSON to response. -func (s defaultJSONSerializer) Write(w http.ResponseWriter, in any, indent string) error { +func (s defaultJSONSerializer) Write(w http.ResponseWriter, in any, indent string) { encoder := json.NewEncoder(w) encoder.SetIndent("", indent) if err := encoder.Encode(in); err != nil { - return newHTTPErrorFromError(http.StatusInternalServerError, err) + panic(err) } - - return nil } // Unmarshal reads request's body as JSON and puts it in the given obj. func (s defaultJSONSerializer) Read(req *http.Request, out any) error { if err := json.NewDecoder(req.Body).Decode(out); err != nil { if _, ok := err.(*json.InvalidUnmarshalError); ok { - return newHTTPErrorFromError(http.StatusInternalServerError, err) + panic(err) } - return newHTTPErrorFromError(http.StatusBadRequest, err) + return err } return nil } diff --git a/serializer/json_test.go b/serializer/json_test.go index 0427a50..c6c8f3d 100644 --- a/serializer/json_test.go +++ b/serializer/json_test.go @@ -1,13 +1,11 @@ package serializer import ( - "encoding/json" "net/http" "net/http/httptest" "strings" "testing" - "github.com/mojixcoder/kid/errors" "github.com/stretchr/testify/assert" ) @@ -29,29 +27,20 @@ func TestDefaultJSONSerializer_Write(t *testing.T) { res := httptest.NewRecorder() p := person{Name: "Mojix", Age: 22} - err := serializer.Write(res, p, "") - assert.NoError(t, err) - + serializer.Write(res, p, "") assert.Equal(t, "{\"name\":\"Mojix\",\"age\":22}\n", res.Body.String()) res = httptest.NewRecorder() - err = serializer.Write(res, p, " ") - assert.NoError(t, err) - + serializer.Write(res, p, " ") assert.Equal(t, "{\n \"name\": \"Mojix\",\n \"age\": 22\n}\n", res.Body.String()) res = httptest.NewRecorder() // Channel type cannot be converted to JSON. - err = serializer.Write(res, make(chan bool), "") - assert.Error(t, err) - - httpErr := err.(*errors.HTTPError) - - assert.Equal(t, http.StatusInternalServerError, httpErr.Code) - assert.Equal(t, httpErr.Err.Error(), httpErr.Message) - assert.Error(t, httpErr.Err) + assert.Panics(t, func() { + serializer.Write(res, make(chan bool), "") + }) } func TestDefaultJSONSerializer_Read(t *testing.T) { @@ -68,24 +57,15 @@ func TestDefaultJSONSerializer_Read(t *testing.T) { req = httptest.NewRequest(http.MethodGet, "/", strings.NewReader("{\"name\":\"Mojix\",\"age\":22}")) - // Invalid argument passed to unmarshal. var p2 person - err = serializer.Read(req, p2) - assert.Error(t, err) - httpErr := err.(*errors.HTTPError) - _, ok := httpErr.Err.(*json.InvalidUnmarshalError) - - assert.Equal(t, http.StatusInternalServerError, httpErr.Code) - assert.Equal(t, httpErr.Err.Error(), httpErr.Message) - assert.Error(t, httpErr.Err) - assert.True(t, ok) + // Invalid argument passed to unmarshal. + assert.Panics(t, func() { + serializer.Read(req, p2) + }) req = httptest.NewRequest(http.MethodGet, "/", strings.NewReader("{\"name\":\"Mojix\",\"age\":22.5}")) err = serializer.Read(req, &p2) - assert.Error(t, err) - assert.Error(t, err.(*errors.HTTPError).Err) - assert.Equal(t, http.StatusBadRequest, err.(*errors.HTTPError).Code) } diff --git a/serializer/serializer.go b/serializer/serializer.go index 94a1906..106b124 100644 --- a/serializer/serializer.go +++ b/serializer/serializer.go @@ -13,7 +13,7 @@ import ( // It can be implemented to read/write custom JSON/XML serializers. type Serializer interface { // Write writes object with the given indent to response body. - Write(w http.ResponseWriter, in any, indent string) error + Write(w http.ResponseWriter, in any, indent string) // Read reads request body and store it in the given object. Read(req *http.Request, out any) error diff --git a/serializer/utils.go b/serializer/utils.go deleted file mode 100644 index 4efb3ea..0000000 --- a/serializer/utils.go +++ /dev/null @@ -1,8 +0,0 @@ -package serializer - -import "github.com/mojixcoder/kid/errors" - -// newHTTPErrorFromError returns a new HTTP error from an error. -func newHTTPErrorFromError(code int, err error) *errors.HTTPError { - return errors.NewHTTPError(code).WithMessage(err.Error()).WithError(err) -} diff --git a/serializer/utils_test.go b/serializer/utils_test.go deleted file mode 100644 index 3e1865c..0000000 --- a/serializer/utils_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package serializer - -import ( - "errors" - "net/http" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestNewHTTPErrorFromError(t *testing.T) { - err := errors.New("test error") - - httpErr := newHTTPErrorFromError(http.StatusBadRequest, err) - - assert.Error(t, httpErr) - assert.Error(t, httpErr.Err) - assert.ErrorIs(t, httpErr.Err, err) - assert.Equal(t, err.Error(), httpErr.Message) - assert.Equal(t, http.StatusBadRequest, httpErr.Code) -} diff --git a/serializer/xml.go b/serializer/xml.go index c234cc5..b1ef0a3 100644 --- a/serializer/xml.go +++ b/serializer/xml.go @@ -18,24 +18,22 @@ func NewXMLSerializer() Serializer { } // Write writes the given object as XML to response. -func (s defaultXMLSerializer) Write(w http.ResponseWriter, in any, indent string) error { +func (s defaultXMLSerializer) Write(w http.ResponseWriter, in any, indent string) { encoder := xml.NewEncoder(w) encoder.Indent("", indent) if err := encoder.Encode(in); err != nil { - return newHTTPErrorFromError(http.StatusInternalServerError, err) + panic(err) } - - return nil } // Read reads request's body as XML and puts it in the given obj. func (s defaultXMLSerializer) Read(req *http.Request, out any) error { if err := xml.NewDecoder(req.Body).Decode(out); err != nil { if err.Error() == "non-pointer passed to Unmarshal" { - return newHTTPErrorFromError(http.StatusInternalServerError, err) + panic(err) } - return newHTTPErrorFromError(http.StatusBadRequest, err) + return err } return nil } diff --git a/serializer/xml_test.go b/serializer/xml_test.go index e6e043f..a341112 100644 --- a/serializer/xml_test.go +++ b/serializer/xml_test.go @@ -6,7 +6,6 @@ import ( "strings" "testing" - "github.com/mojixcoder/kid/errors" "github.com/stretchr/testify/assert" ) @@ -24,27 +23,18 @@ func TestDefaultXMLSerializer_Write(t *testing.T) { p := person{Name: "Mojix", Age: 22} - err := serializer.Write(res, p, "") - - assert.NoError(t, err) + serializer.Write(res, p, "") assert.Equal(t, "