Skip to content

Commit e060d20

Browse files
committed
utility handler fn extraction
1 parent 819f6f6 commit e060d20

File tree

4 files changed

+31
-26
lines changed

4 files changed

+31
-26
lines changed

internal/rest/api_work_item.go

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
package rest
22

33
import (
4-
"bytes"
54
"encoding/json"
6-
"io"
75
"net/http"
86

97
"github.com/danicc097/openapi-go-gin-postgres-sqlc/internal"
108
"github.com/danicc097/openapi-go-gin-postgres-sqlc/internal/repos"
119
"github.com/danicc097/openapi-go-gin-postgres-sqlc/internal/repos/postgresql/gen/models"
1210
"github.com/danicc097/openapi-go-gin-postgres-sqlc/internal/services"
13-
"github.com/danicc097/openapi-go-gin-postgres-sqlc/internal/tracing"
1411
"github.com/gin-gonic/gin"
1512
)
1613

@@ -29,28 +26,14 @@ func (h *StrictHandlers) DeleteWorkitem(c *gin.Context, request DeleteWorkitemRe
2926
func (h *StrictHandlers) CreateWorkitem(c *gin.Context, request CreateWorkitemRequestObject) (CreateWorkitemResponseObject, error) {
3027
ctx := c.Request.Context()
3128

32-
span := GetSpanFromCtx(c)
33-
3429
caller, _ := GetUserCallerFromCtx(c)
3530
tx := GetTxFromCtx(c)
3631

37-
jsonBody, err := io.ReadAll(c.Request.Body)
38-
if err != nil {
39-
renderErrorResponse(c, "Failed to read request body", err)
40-
}
41-
span.SetAttributes(tracing.MetadataAttribute(jsonBody))
42-
c.Request.Body = io.NopCloser(bytes.NewBuffer(jsonBody))
43-
44-
project, err := projectByDiscriminator(request.Body)
45-
if err != nil {
46-
renderErrorResponse(c, "Failed to get project", err)
47-
}
32+
addRequestBodyToSpan(c)
4833

4934
var res any // depends on project
50-
b, err := request.Body.ValueByDiscriminator()
51-
if err != nil {
52-
renderErrorResponse(c, "Failed to read discriminator", err)
53-
}
35+
36+
project, b := projectAndBodyByDiscriminator(c, request.Body)
5437

5538
//exhaustive:enforce
5639
switch project {

internal/rest/discriminator.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
package rest
22

33
import (
4-
"fmt"
5-
64
"github.com/danicc097/openapi-go-gin-postgres-sqlc/internal/repos/postgresql/gen/models"
5+
"github.com/gin-gonic/gin"
76
)
87

98
type PolymorphicBody interface {
109
Discriminator() (string, error)
10+
ValueByDiscriminator() (interface{}, error)
1111
}
1212

13-
func projectByDiscriminator(b PolymorphicBody) (models.ProjectName, error) {
14-
d, err := b.Discriminator()
13+
func projectAndBodyByDiscriminator(c *gin.Context, body PolymorphicBody) (models.ProjectName, interface{}) {
14+
d, err := body.Discriminator()
15+
if err != nil {
16+
renderErrorResponse(c, "could not get project discriminator: %w", err)
17+
}
18+
19+
b, err := body.ValueByDiscriminator()
1520
if err != nil {
16-
return "", fmt.Errorf("could not get project discriminator: %w", err)
21+
renderErrorResponse(c, "could not convert body: %w", err)
1722
}
1823

19-
return models.ProjectName(d), nil
24+
return models.ProjectName(d), b
2025
}

internal/rest/otel.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package rest
22

33
import (
4+
"bytes"
5+
"io"
6+
47
"github.com/danicc097/openapi-go-gin-postgres-sqlc/internal"
58
"github.com/danicc097/openapi-go-gin-postgres-sqlc/internal/tracing"
69
"github.com/gin-gonic/gin"
@@ -38,3 +41,14 @@ func newOTelSpanWithUser(c *gin.Context, opts ...trace.SpanStartOption) trace.Sp
3841

3942
return builder.Build(c.Request.Context())
4043
}
44+
45+
func addRequestBodyToSpan(c *gin.Context) {
46+
span := GetSpanFromCtx(c)
47+
48+
jsonBody, err := io.ReadAll(c.Request.Body)
49+
if err != nil {
50+
renderErrorResponse(c, "Failed to read request body", err)
51+
}
52+
span.SetAttributes(tracing.MetadataAttribute(jsonBody))
53+
c.Request.Body = io.NopCloser(bytes.NewBuffer(jsonBody))
54+
}

internal/rest/responses.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ func WithoutPanic() RenderErrorOption {
3838
}
3939

4040
// renderErrorResponse writes an error response from title and error.
41+
// When used inside a StrictHandlers' handler, it panics with a HandlerExitError which
42+
// is recovered immediately by the handler wrapper.
43+
// When used outside a StrictHandlers' handler, WithoutPanic must be used to prevent unrecovered panics.
4144
// title represents an error title which will be shown to end users.
4245
// Inspired by https://www.rfc-editor.org/rfc/rfc7807.
4346
func renderErrorResponse(c *gin.Context, title string, err error, opts ...RenderErrorOption) {

0 commit comments

Comments
 (0)