Skip to content

Commit

Permalink
handler panic for rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
danicc097 committed Jan 19, 2025
1 parent c488de4 commit 819f6f6
Show file tree
Hide file tree
Showing 15 changed files with 522 additions and 76 deletions.
8 changes: 0 additions & 8 deletions bin/templates/crud-api.go.tmpl.bash
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ $(test -n "$with_project" && echo " params.ProjectID = internal.ProjectIDByName[
${camel_name}, err := h.svc.${pascal_name}.Create(c, tx, &params)
if err != nil {
renderErrorResponse(c, "Could not create ${sentence_name}", err)
return nil, nil
}
res := ${pascal_name}Response{
Expand All @@ -36,8 +34,6 @@ func (h *StrictHandlers) Get${pascal_name}(c *gin.Context, request Get${pascal_n
${camel_name}, err := h.svc.${pascal_name}.ByID(c, tx, request.${pascal_name}ID)
if err != nil {
renderErrorResponse(c, "Could not create ${sentence_name}", err)
return nil, nil
}
res := ${pascal_name}Response{
Expand All @@ -56,8 +52,6 @@ func (h *StrictHandlers) Update${pascal_name}(c *gin.Context, request Update${pa
${camel_name}, err := h.svc.${pascal_name}.Update(c, tx, request.${pascal_name}ID, &params)
if err != nil {
renderErrorResponse(c, "Could not update ${sentence_name}", err)
return nil, nil
}
res := ${pascal_name}Response{
Expand All @@ -74,8 +68,6 @@ func (h *StrictHandlers) Delete${pascal_name}(c *gin.Context, request Delete${pa
_, err := h.svc.${pascal_name}.Delete(c, tx, request.${pascal_name}ID)
if err != nil {
renderErrorResponse(c, "Could not delete ${sentence_name}", err)
return nil, nil
}
return Delete${pascal_name}204Response{}, nil
Expand Down
10 changes: 10 additions & 0 deletions cmd/oapi-codegen/oapi-templates/strict/strict-gin.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ func (sh *strictHandlers) authMiddlewares(opID OperationID) []gin.HandlerFunc {
{{$opid := .OperationId}}
// {{$opid}} operation middleware
func (sh *strictHandlers) {{.OperationId}}(ctx *gin.Context{{genParamArgs .PathParams}}{{if .RequiresParamObject}}, params externalRef0.{{.OperationId}}Params{{end}}) {
defer func() {
if r := recover(); r != nil {
// handler() may panic to notify early handler exit
if _, ok := r.(*HandlerExitError); !ok {
panic(r)
}
// swallow panic, assume error response was rendered already to gin context
}
}()

var request {{$opid | ucFirst}}RequestObject

{{range .PathParams -}}
Expand Down
8 changes: 0 additions & 8 deletions internal/rest/api_activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ func (h *StrictHandlers) CreateActivity(c *gin.Context, request CreateActivityRe
activity, err := h.svc.Activity.Create(c.Request.Context(), h.pool, request.ProjectName, &request.Body.ActivityCreateParams)
if err != nil {
renderErrorResponse(c, "could not create activity", err)

return nil, nil
}

return CreateActivity201JSONResponse{Activity: *activity}, nil
Expand All @@ -18,8 +16,6 @@ func (h *StrictHandlers) CreateActivity(c *gin.Context, request CreateActivityRe
func (h *StrictHandlers) DeleteActivity(c *gin.Context, request DeleteActivityRequestObject) (DeleteActivityResponseObject, error) {
if _, err := h.svc.Activity.Delete(c.Request.Context(), h.pool, request.ActivityID); err != nil {
renderErrorResponse(c, "could not delete activity", err)

return nil, nil
}

return DeleteActivity204Response{}, nil
Expand All @@ -29,8 +25,6 @@ func (h *StrictHandlers) GetActivity(c *gin.Context, request GetActivityRequestO
activity, err := h.svc.Activity.ByID(c.Request.Context(), h.pool, request.ActivityID)
if err != nil {
renderErrorResponse(c, "could not get activity", err)

return nil, nil
}

return GetActivity200JSONResponse{Activity: *activity}, nil
Expand All @@ -40,8 +34,6 @@ func (h *StrictHandlers) UpdateActivity(c *gin.Context, request UpdateActivityRe
activity, err := h.svc.Activity.Update(c.Request.Context(), h.pool, request.ActivityID, &request.Body.ActivityUpdateParams)
if err != nil {
renderErrorResponse(c, "could not update activity", err)

return nil, nil
}

return UpdateActivity200JSONResponse{Activity: *activity}, nil
Expand Down
2 changes: 0 additions & 2 deletions internal/rest/api_notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ func (h *StrictHandlers) GetPaginatedNotifications(c *gin.Context, request GetPa
nn, err := h.svc.Notification.PaginatedUserNotifications(c.Request.Context(), h.pool, caller.UserID, request.Params)
if err != nil {
renderErrorResponse(c, "Could not fetch notifications", err)

return nil, nil
}

nextCursor := ""
Expand Down
3 changes: 0 additions & 3 deletions internal/rest/api_oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,18 @@ func (h *StrictHandlers) MyProviderCallback(c *gin.Context, request MyProviderCa
userinfo, err := GetUserInfoFromCtx(c)
if err != nil {
renderErrorResponse(c, "OIDC authentication error", internal.WrapErrorf(err, models.ErrorCodeOIDC, "user info not found"))
return nil, nil
}

ctx := c.Request.Context()

u, err := h.svc.Authentication.GetOrRegisterUserFromUserInfo(ctx, *userinfo)
if err != nil {
renderErrorResponse(c, "OIDC authentication error", internal.WrapErrorf(err, models.ErrorCodeOIDC, "could not get or register user"))
return nil, nil
}

accessToken, err := h.svc.Authentication.CreateAccessTokenForUser(ctx, u)
if err != nil {
renderErrorResponse(c, "OIDC authentication error", internal.WrapErrorf(err, models.ErrorCodeOIDC, "could not create access token"))
return nil, nil
}

http.SetCookie(c.Writer, &http.Cookie{
Expand Down
8 changes: 0 additions & 8 deletions internal/rest/api_team.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ func (h *StrictHandlers) CreateTeam(c *gin.Context, request CreateTeamRequestObj
team, err := h.svc.Team.Create(ctx, tx, &params)
if err != nil {
renderErrorResponse(c, "Could not create team", err)

return nil, nil
}

h.event.Queue(ctx, fmt.Sprintf("team created: %v", team.TeamID), models.TopicTeamCreated)
Expand All @@ -36,8 +34,6 @@ func (h *StrictHandlers) UpdateTeam(c *gin.Context, request UpdateTeamRequestObj
team, err := h.svc.Team.Update(ctx, tx, models.TeamID(request.TeamID), &params)
if err != nil {
renderErrorResponse(c, "Could not update team", err)

return nil, nil
}

return UpdateTeam200JSONResponse{Team: *team}, nil
Expand All @@ -50,8 +46,6 @@ func (h *StrictHandlers) GetTeam(c *gin.Context, request GetTeamRequestObject) (
team, err := h.svc.Team.ByID(ctx, tx, models.TeamID(request.TeamID))
if err != nil {
renderErrorResponse(c, "Could not get team", err)

return nil, nil
}

return GetTeam200JSONResponse{Team: *team}, nil
Expand All @@ -64,8 +58,6 @@ func (h *StrictHandlers) DeleteTeam(c *gin.Context, request DeleteTeamRequestObj
_, err := h.svc.Team.Delete(ctx, tx, models.TeamID(request.TeamID))
if err != nil {
renderErrorResponse(c, "Could not delete team", err)

return nil, nil
}

return DeleteTeam204Response{}, nil
Expand Down
14 changes: 0 additions & 14 deletions internal/rest/api_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,11 @@ func (h *StrictHandlers) UpdateUser(c *gin.Context, request UpdateUserRequestObj
user, err := h.svc.User.Update(c, tx, models.UserID{UUID: request.Id}, caller, request.Body)
if err != nil {
renderErrorResponse(c, "Could not update user", err)

return nil, nil
}

role, ok := h.svc.Authorization.RoleByRank(user.RoleRank)
if !ok {
renderErrorResponse(c, fmt.Sprintf("Role with rank %d not found", user.RoleRank), nil)

return nil, nil
}

res := UserResponse{User: user, Role: role.Name}
Expand All @@ -43,8 +39,6 @@ func (h *StrictHandlers) DeleteUser(c *gin.Context, request DeleteUserRequestObj
_, err := h.svc.User.Delete(c, tx, models.NewUserID(request.Id))
if err != nil {
renderErrorResponse(c, "Could not delete user", err)

return nil, nil
}

return DeleteUser204Response{}, nil
Expand All @@ -57,8 +51,6 @@ func (h *StrictHandlers) GetCurrentUser(c *gin.Context, request GetCurrentUserRe
if !ok {
msg := fmt.Sprintf("role with rank %d not found", caller.RoleRank)
renderErrorResponse(c, msg, errors.New(msg))

return nil, nil
}

res := UserResponse{
Expand All @@ -82,8 +74,6 @@ func (h *StrictHandlers) UpdateUserAuthorization(c *gin.Context, request UpdateU

if _, err := h.svc.User.UpdateUserAuthorization(c, tx, models.UserID{UUID: request.Id}, caller, request.Body); err != nil {
renderErrorResponse(c, "Error updating user authorization", err)

return nil, nil
}

return UpdateUserAuthorization204Response{}, nil
Expand All @@ -93,8 +83,6 @@ func (h *StrictHandlers) GetPaginatedUsers(c *gin.Context, request GetPaginatedU
users, err := h.svc.User.Paginated(c, h.pool, request.Params)
if err != nil {
renderErrorResponse(c, "Could not update user", err)

return nil, nil
}

nextCursor := ""
Expand All @@ -103,8 +91,6 @@ func (h *StrictHandlers) GetPaginatedUsers(c *gin.Context, request GetPaginatedU
nextCursor, err = getNextCursor(lastUser, request.Params.Column, models.TableEntityUser)
if err != nil {
renderErrorResponse(c, "Could not define next cursor", err)

return nil, nil
}
}
items := make([]UserResponse, len(users))
Expand Down
12 changes: 0 additions & 12 deletions internal/rest/api_work_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,19 @@ func (h *StrictHandlers) CreateWorkitem(c *gin.Context, request CreateWorkitemRe
jsonBody, err := io.ReadAll(c.Request.Body)
if err != nil {
renderErrorResponse(c, "Failed to read request body", err)

return nil, nil
}
span.SetAttributes(tracing.MetadataAttribute(jsonBody))
c.Request.Body = io.NopCloser(bytes.NewBuffer(jsonBody))

project, err := projectByDiscriminator(request.Body)
if err != nil {
renderErrorResponse(c, "Failed to get project", err)

return nil, nil
}

var res any // depends on project
b, err := request.Body.ValueByDiscriminator()
if err != nil {
renderErrorResponse(c, "Failed to read discriminator", err)

return nil, nil
}

//exhaustive:enforce
Expand All @@ -74,8 +68,6 @@ func (h *StrictHandlers) CreateWorkitem(c *gin.Context, request CreateWorkitemRe
})
if err != nil {
renderErrorResponse(c, "Could not create work item", err)

return nil, nil
}

res = DemoWorkItemResponse{
Expand All @@ -96,8 +88,6 @@ func (h *StrictHandlers) CreateWorkitem(c *gin.Context, request CreateWorkitemRe
})
if err != nil {
renderErrorResponse(c, "Could not create work item", err)

return nil, nil
}

res = DemoTwoWorkItemResponse{
Expand All @@ -106,8 +96,6 @@ func (h *StrictHandlers) CreateWorkitem(c *gin.Context, request CreateWorkitemRe
}
default:
renderErrorResponse(c, "Unknown discriminator", internal.NewErrorf(models.ErrorCodeUnknown, "%+v", b))

return nil, nil
}

var resJson *CreateWorkitem201JSONResponse
Expand Down
8 changes: 0 additions & 8 deletions internal/rest/api_work_item_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ func (h *StrictHandlers) CreateWorkItemComment(c *gin.Context, request CreateWor
workItemComment, err := h.svc.WorkItemComment.Create(c, tx, &params)
if err != nil {
renderErrorResponse(c, "Could not create work item comment", err)

return nil, nil
}

res := WorkItemCommentResponse{
Expand All @@ -31,8 +29,6 @@ func (h *StrictHandlers) GetWorkItemComment(c *gin.Context, request GetWorkItemC
workItemComment, err := h.svc.WorkItemComment.ByID(c, tx, request.WorkItemCommentID)
if err != nil {
renderErrorResponse(c, "Could not create work item comment", err)

return nil, nil
}

res := WorkItemCommentResponse{
Expand All @@ -52,8 +48,6 @@ func (h *StrictHandlers) UpdateWorkItemComment(c *gin.Context, request UpdateWor
workItemComment, err := h.svc.WorkItemComment.Update(c, tx, caller, models.WorkItemCommentID(request.WorkItemCommentID), &params)
if err != nil {
renderErrorResponse(c, "Could not update work item comment", err)

return nil, nil
}

res := WorkItemCommentResponse{
Expand All @@ -71,8 +65,6 @@ func (h *StrictHandlers) DeleteWorkItemComment(c *gin.Context, request DeleteWor
_, err := h.svc.WorkItemComment.Delete(c, tx, caller, models.WorkItemCommentID(request.WorkItemCommentID))
if err != nil {
renderErrorResponse(c, "Could not delete work item comment", err)

return nil, nil
}

return DeleteWorkItemComment204Response{}, nil
Expand Down
2 changes: 0 additions & 2 deletions internal/rest/api_work_item_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ func (h *StrictHandlers) CreateWorkItemTag(c *gin.Context, request CreateWorkIte
wit, err := h.svc.WorkItemTag.Create(ctx, tx, caller, &body.WorkItemTagCreateParams)
if err != nil {
renderErrorResponse(c, "Could not create work item tag", err)

return nil, nil
}

return CreateWorkItemTag201JSONResponse{WorkItemTag: *wit}, nil
Expand Down
12 changes: 6 additions & 6 deletions internal/rest/middleware.auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (m *authMiddleware) EnsureAuthenticated() gin.HandlerFunc {
if apiKey != "" {
u, err := m.svc.Authentication.GetUserFromAPIKey(c.Request.Context(), apiKey) // includes caller joins
if err != nil || u == nil {
renderErrorResponse(c, "Unauthenticated", internal.NewErrorf(models.ErrorCodeUnauthenticated, "could not get user from api key"))
renderErrorResponse(c, "Unauthenticated", internal.NewErrorf(models.ErrorCodeUnauthenticated, "could not get user from api key"), WithoutPanic())
c.Abort()

return
Expand All @@ -60,7 +60,7 @@ func (m *authMiddleware) EnsureAuthenticated() gin.HandlerFunc {
if strings.HasPrefix(auth, "Bearer ") {
u, err := m.svc.Authentication.GetUserFromAccessToken(c.Request.Context(), strings.Split(auth, "Bearer ")[1]) // includes caller joins
if err != nil || u == nil {
renderErrorResponse(c, "Unauthenticated", internal.NewErrorf(models.ErrorCodeUnauthenticated, "could not get user from token: %s", err))
renderErrorResponse(c, "Unauthenticated", internal.NewErrorf(models.ErrorCodeUnauthenticated, "could not get user from token: %s", err), WithoutPanic())
c.Abort()

return
Expand All @@ -73,7 +73,7 @@ func (m *authMiddleware) EnsureAuthenticated() gin.HandlerFunc {
return
}

renderErrorResponse(c, "Unauthenticated", internal.NewErrorf(models.ErrorCodeUnauthenticated, "could not get user from token"))
renderErrorResponse(c, "Unauthenticated", internal.NewErrorf(models.ErrorCodeUnauthenticated, "could not get user from token"), WithoutPanic())
c.Abort()
}
}
Expand All @@ -91,7 +91,7 @@ func (m *authMiddleware) EnsureAuthorized(config AuthRestriction) gin.HandlerFun
errs := []string{}
user, err := GetUserCallerFromCtx(c)
if err != nil {
renderErrorResponse(c, "Could not get current user.", nil)
renderErrorResponse(c, "Could not get current user.", nil, WithoutPanic())
c.Abort()

return
Expand All @@ -100,7 +100,7 @@ func (m *authMiddleware) EnsureAuthorized(config AuthRestriction) gin.HandlerFun
if config.MinimumRole != "" {
userRole, ok := m.svc.Authorization.RoleByRank(user.RoleRank)
if !ok {
renderErrorResponse(c, fmt.Sprintf("Unknown rank value: %d", user.RoleRank), errors.New("unknown rank"))
renderErrorResponse(c, fmt.Sprintf("Unknown rank value: %d", user.RoleRank), errors.New("unknown rank"), WithoutPanic())
c.Abort()

return
Expand Down Expand Up @@ -129,7 +129,7 @@ func (m *authMiddleware) EnsureAuthorized(config AuthRestriction) gin.HandlerFun
errorMsg = fmt.Sprintf("either %s are required", slices.Join(errs, " or "))
}

renderErrorResponse(c, "Unauthorized", internal.NewErrorf(models.ErrorCodeUnauthorized, "unauthorized: "+errorMsg))
renderErrorResponse(c, "Unauthorized", internal.NewErrorf(models.ErrorCodeUnauthorized, "unauthorized: "+errorMsg), WithoutPanic())
c.Abort()
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/rest/middleware.db.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (m *dbMiddleware) BeginTransaction() gin.HandlerFunc {

tx, err := m.pool.BeginTx(ctx, pgx.TxOptions{})
if err != nil {
renderErrorResponse(c, "", internal.WrapErrorf(err, models.ErrorCodePrivate, "could not begin transaction"))
renderErrorResponse(c, "", internal.WrapErrorf(err, models.ErrorCodePrivate, "could not begin transaction"), WithoutPanic())
c.Abort()

return
Expand Down
Loading

0 comments on commit 819f6f6

Please sign in to comment.