removed intermediate /internal directory
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"ruben/inventory2/consts"
|
||||
)
|
||||
|
||||
func HandleResponses(c *gin.Context) {
|
||||
c.Next()
|
||||
|
||||
if len(c.Errors) > 0 || c.Writer.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
v, ok := c.Get(responseKey{})
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
res, ok := v.(Response)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
writeResponse(c, res)
|
||||
}
|
||||
|
||||
func HandleErrors(c *gin.Context) {
|
||||
c.Next()
|
||||
|
||||
if len(c.Errors) == 0 || c.Writer.Written() {
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
err ErrorResponse
|
||||
ok bool
|
||||
)
|
||||
for _, e := range c.Errors {
|
||||
if err, ok = GetError(e); ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
var (
|
||||
err error
|
||||
status int
|
||||
statusFound bool
|
||||
)
|
||||
for _, e := range c.Errors {
|
||||
err = errors.Join(err, e)
|
||||
if !statusFound {
|
||||
status, statusFound = mapErrorConstantsToStatus(e)
|
||||
}
|
||||
}
|
||||
|
||||
if !statusFound {
|
||||
status = http.StatusInternalServerError
|
||||
}
|
||||
|
||||
c.String(status, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
status, ok := err.GetStatus()
|
||||
if !ok {
|
||||
status = http.StatusInternalServerError
|
||||
}
|
||||
if h, ok := err.GetHTML(); ok {
|
||||
c.Status(status)
|
||||
c.Header("Content-Type", "text/html")
|
||||
c.Writer.Write(h)
|
||||
return
|
||||
}
|
||||
|
||||
msg, ok := err.GetMsg()
|
||||
if !ok {
|
||||
msg = err.Error()
|
||||
}
|
||||
c.String(status, msg)
|
||||
}
|
||||
|
||||
func writeResponse(c *gin.Context, res Response) {
|
||||
w := c.Writer
|
||||
|
||||
// w.Header() must be set before ResponseWriter.WriteHeader is called
|
||||
// or redirect is attempted
|
||||
hdrs := w.Header()
|
||||
for _, hdr := range res.getHeaders() {
|
||||
hdrs.Add(hdr[0], hdr[1])
|
||||
}
|
||||
|
||||
for _, ck := range res.getCookies() {
|
||||
hdrs.Add("Set-Cookie", ck.String())
|
||||
}
|
||||
|
||||
if ct, ok := res.getContentType(); ok {
|
||||
hdrs.Set("Content-Type", ct)
|
||||
}
|
||||
|
||||
if code, to, ok := res.GetRedirect(); ok {
|
||||
c.Redirect(code.Int(), to)
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
// the body is written after the status header, but it's read here
|
||||
// first, because if an error is incurred, an error status header will
|
||||
// need to be written.
|
||||
body, bodySet, err := res.getBody()
|
||||
if err != nil {
|
||||
http.Error(
|
||||
w,
|
||||
fmt.Sprintf("Failed to construct response body: %v", err.Error()),
|
||||
http.StatusInternalServerError,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if status, ok := res.GetStatus(); ok {
|
||||
w.WriteHeader(status)
|
||||
}
|
||||
if bodySet {
|
||||
// will automatically set the status header,
|
||||
// if w.WriteHeader wasn't already called
|
||||
io.Copy(w, body)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func GetStatusFromError(err error) int {
|
||||
status := http.StatusInternalServerError
|
||||
|
||||
if e, ok := GetError(err); ok {
|
||||
if status, ok = e.GetStatus(); !ok {
|
||||
status = http.StatusInternalServerError
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
|
||||
func mapErrorConstantsToStatus(err error) (int, bool) {
|
||||
for {
|
||||
switch err {
|
||||
case consts.ErrBadRequest:
|
||||
return http.StatusBadRequest, true
|
||||
case consts.ErrNotFound:
|
||||
return http.StatusNotFound, true
|
||||
case consts.ErrConflict:
|
||||
return http.StatusConflict, true
|
||||
default:
|
||||
werr, ok := err.(interface {
|
||||
Unwrap() error
|
||||
})
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
err = werr.Unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user