Internal server error page

This commit is contained in:
Asaf Gartner 2021-08-28 15:21:03 +03:00
parent a655fe96bc
commit cb5c3c403d
16 changed files with 186 additions and 148 deletions

View File

@ -0,0 +1,16 @@
{{ template "base.html" . }}
{{ define "content" }}
<div class="description">
<p>
<span class="big">Hi there, {{ if .User }}{{ .User.Name }}{{ else }}visitor{{ end }}!</span>
</p>
<p>
<span class="big">
We have encountered an error while processing your request.
<br />
If this keeps happening, please <a href="{{ .ReportIssueMailto }}">let us know</a>.
</span>
</p>
</div>
{{ end }}

View File

@ -6,14 +6,15 @@ import (
) )
type BaseData struct { type BaseData struct {
Title string Title string
CanonicalLink string CanonicalLink string
OpenGraphItems []OpenGraphItem OpenGraphItems []OpenGraphItem
BackgroundImage BackgroundImage BackgroundImage BackgroundImage
Theme string Theme string
BodyClasses []string BodyClasses []string
Breadcrumbs []Breadcrumb Breadcrumbs []Breadcrumb
Notices []Notice Notices []Notice
ReportIssueMailto string
CurrentUrl string CurrentUrl string
LoginPageUrl string LoginPageUrl string

View File

@ -53,7 +53,7 @@ func Login(c *RequestContext) ResponseData {
form, err := c.GetFormValues() form, err := c.GetFormValues()
if err != nil { if err != nil {
return ErrorResponse(http.StatusBadRequest, NewSafeError(err, "request must contain form data")) return c.ErrorResponse(http.StatusBadRequest, NewSafeError(err, "request must contain form data"))
} }
redirect := form.Get("redirect") redirect := form.Get("redirect")
@ -84,7 +84,7 @@ func Login(c *RequestContext) ResponseData {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
return showLoginWithFailure(c, redirect) return showLoginWithFailure(c, redirect)
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to look up user by username")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to look up user by username"))
} }
} }
user := userRow.(*models.User) user := userRow.(*models.User)
@ -92,7 +92,7 @@ func Login(c *RequestContext) ResponseData {
success, err := tryLogin(c, user, password) success, err := tryLogin(c, user, password)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if !success { if !success {
@ -106,7 +106,7 @@ func Login(c *RequestContext) ResponseData {
res := c.Redirect(redirect, http.StatusSeeOther) res := c.Redirect(redirect, http.StatusSeeOther)
err = loginUser(c, user, &res) err = loginUser(c, user, &res)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
return res return res
} }
@ -179,7 +179,7 @@ func RegisterNewUserSubmit(c *RequestContext) ResponseData {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
userAlreadyExists = false userAlreadyExists = false
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user"))
} }
} }
@ -200,7 +200,7 @@ func RegisterNewUserSubmit(c *RequestContext) ResponseData {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
emailAlreadyExists = false emailAlreadyExists = false
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user"))
} }
} }
c.Perf.EndBlock() c.Perf.EndBlock()
@ -215,7 +215,7 @@ func RegisterNewUserSubmit(c *RequestContext) ResponseData {
c.Perf.StartBlock("SQL", "Create user and one time token") c.Perf.StartBlock("SQL", "Create user and one time token")
tx, err := c.Conn.Begin(c.Context()) tx, err := c.Conn.Begin(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to start db transaction")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to start db transaction"))
} }
defer tx.Rollback(c.Context()) defer tx.Rollback(c.Context())
@ -231,7 +231,7 @@ func RegisterNewUserSubmit(c *RequestContext) ResponseData {
username, emailAddress, hashed.String(), now, displayName, c.GetIP(), username, emailAddress, hashed.String(), now, displayName, c.GetIP(),
).Scan(&newUserId) ).Scan(&newUserId)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to store user")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to store user"))
} }
ott := models.GenerateToken() ott := models.GenerateToken()
@ -247,7 +247,7 @@ func RegisterNewUserSubmit(c *RequestContext) ResponseData {
newUserId, newUserId,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to store one-time token")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to store one-time token"))
} }
c.Perf.EndBlock() c.Perf.EndBlock()
@ -257,13 +257,13 @@ func RegisterNewUserSubmit(c *RequestContext) ResponseData {
} }
err = email.SendRegistrationEmail(emailAddress, mailName, username, ott, c.Perf) err = email.SendRegistrationEmail(emailAddress, mailName, username, ott, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to send registration email")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to send registration email"))
} }
c.Perf.StartBlock("SQL", "Commit user") c.Perf.StartBlock("SQL", "Commit user")
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit user to the db")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit user to the db"))
} }
c.Perf.EndBlock() c.Perf.EndBlock()
return c.Redirect(hmnurl.BuildRegistrationSuccess(), http.StatusSeeOther) return c.Redirect(hmnurl.BuildRegistrationSuccess(), http.StatusSeeOther)
@ -349,7 +349,7 @@ func EmailConfirmationSubmit(c *RequestContext) ResponseData {
success, err := tryLogin(c, validationResult.User, password) success, err := tryLogin(c, validationResult.User, password)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} else if !success { } else if !success {
var res ResponseData var res ResponseData
baseData := getBaseData(c) baseData := getBaseData(c)
@ -366,7 +366,7 @@ func EmailConfirmationSubmit(c *RequestContext) ResponseData {
c.Perf.StartBlock("SQL", "Updating user status and deleting token") c.Perf.StartBlock("SQL", "Updating user status and deleting token")
tx, err := c.Conn.Begin(c.Context()) tx, err := c.Conn.Begin(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to start db transaction")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to start db transaction"))
} }
defer tx.Rollback(c.Context()) defer tx.Rollback(c.Context())
@ -380,7 +380,7 @@ func EmailConfirmationSubmit(c *RequestContext) ResponseData {
validationResult.User.ID, validationResult.User.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user status")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user status"))
} }
_, err = tx.Exec(c.Context(), _, err = tx.Exec(c.Context(),
@ -390,12 +390,12 @@ func EmailConfirmationSubmit(c *RequestContext) ResponseData {
validationResult.OneTimeToken.ID, validationResult.OneTimeToken.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete one time token")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete one time token"))
} }
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit transaction")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit transaction"))
} }
c.Perf.EndBlock() c.Perf.EndBlock()
@ -403,7 +403,7 @@ func EmailConfirmationSubmit(c *RequestContext) ResponseData {
res.AddFutureNotice("success", "You've completed your registration successfully!") res.AddFutureNotice("success", "You've completed your registration successfully!")
err = loginUser(c, validationResult.User, &res) err = loginUser(c, validationResult.User, &res)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
return res return res
} }
@ -464,7 +464,7 @@ func RequestPasswordResetSubmit(c *RequestContext) ResponseData {
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
if !errors.Is(err, db.ErrNoMatchingRows) { if !errors.Is(err, db.ErrNoMatchingRows) {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to look up user by username")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to look up user by username"))
} }
} }
if userRow != nil { if userRow != nil {
@ -487,7 +487,7 @@ func RequestPasswordResetSubmit(c *RequestContext) ResponseData {
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
if !errors.Is(err, db.ErrNoMatchingRows) { if !errors.Is(err, db.ErrNoMatchingRows) {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch onetimetoken for user")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch onetimetoken for user"))
} }
} }
var resetToken *models.OneTimeToken var resetToken *models.OneTimeToken
@ -508,7 +508,7 @@ func RequestPasswordResetSubmit(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete onetimetoken")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete onetimetoken"))
} }
resetToken = nil resetToken = nil
} }
@ -530,13 +530,13 @@ func RequestPasswordResetSubmit(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create onetimetoken")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create onetimetoken"))
} }
resetToken = tokenRow.(*models.OneTimeToken) resetToken = tokenRow.(*models.OneTimeToken)
err = email.SendPasswordReset(user.Email, user.BestName(), user.Username, resetToken.Content, resetToken.Expires, c.Perf) err = email.SendPasswordReset(user.Email, user.BestName(), user.Username, resetToken.Content, resetToken.Expires, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to send email")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to send email"))
} }
} }
} }
@ -624,7 +624,7 @@ func DoPasswordResetSubmit(c *RequestContext) ResponseData {
c.Perf.StartBlock("SQL", "Update user's password and delete reset token") c.Perf.StartBlock("SQL", "Update user's password and delete reset token")
tx, err := c.Conn.Begin(c.Context()) tx, err := c.Conn.Begin(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to start db transaction")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to start db transaction"))
} }
defer tx.Rollback(c.Context()) defer tx.Rollback(c.Context())
@ -638,7 +638,7 @@ func DoPasswordResetSubmit(c *RequestContext) ResponseData {
validationResult.User.ID, validationResult.User.ID,
) )
if err != nil || tag.RowsAffected() == 0 { if err != nil || tag.RowsAffected() == 0 {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user's password")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user's password"))
} }
if validationResult.User.Status == models.UserStatusInactive { if validationResult.User.Status == models.UserStatusInactive {
@ -652,7 +652,7 @@ func DoPasswordResetSubmit(c *RequestContext) ResponseData {
validationResult.User.ID, validationResult.User.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user's status")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user's status"))
} }
} }
@ -664,12 +664,12 @@ func DoPasswordResetSubmit(c *RequestContext) ResponseData {
validationResult.OneTimeToken.ID, validationResult.OneTimeToken.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete onetimetoken")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete onetimetoken"))
} }
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit password reset to the db")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit password reset to the db"))
} }
c.Perf.EndBlock() c.Perf.EndBlock()
@ -677,7 +677,7 @@ func DoPasswordResetSubmit(c *RequestContext) ResponseData {
res.AddFutureNotice("success", "Password changed successfully.") res.AddFutureNotice("success", "Password changed successfully.")
err = loginUser(c, validationResult.User, &res) err = loginUser(c, validationResult.User, &res)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
return res return res
} }

View File

@ -50,7 +50,7 @@ func BlogIndex(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch total number of blog posts")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch total number of blog posts"))
} }
numPages := NumPages(numPosts, postsPerPage) numPages := NumPages(numPosts, postsPerPage)
@ -88,7 +88,7 @@ func BlogIndex(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch blog posts for index")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch blog posts for index"))
} }
var entries []blogIndexEntry var entries []blogIndexEntry
@ -112,7 +112,7 @@ func BlogIndex(c *RequestContext) ResponseData {
isProjectOwner := false isProjectOwner := false
owners, err := FetchProjectOwners(c, c.CurrentProject.ID) owners, err := FetchProjectOwners(c, c.CurrentProject.ID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project owners")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project owners"))
} }
for _, owner := range owners { for _, owner := range owners {
if owner.ID == c.CurrentUser.ID { if owner.ID == c.CurrentUser.ID {
@ -232,7 +232,7 @@ func BlogNewThreadSubmit(c *RequestContext) ResponseData {
err = c.Req.ParseForm() err = c.Req.ParseForm()
if err != nil { if err != nil {
return ErrorResponse(http.StatusBadRequest, oops.New(err, "the form data was invalid")) return c.ErrorResponse(http.StatusBadRequest, oops.New(err, "the form data was invalid"))
} }
title := c.Req.Form.Get("title") title := c.Req.Form.Get("title")
unparsed := c.Req.Form.Get("body") unparsed := c.Req.Form.Get("body")
@ -266,7 +266,7 @@ func BlogNewThreadSubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create new blog post")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create new blog post"))
} }
newThreadUrl := hmnurl.BuildBlogThread(c.CurrentProject.Slug, threadId, title) newThreadUrl := hmnurl.BuildBlogThread(c.CurrentProject.Slug, threadId, title)
@ -339,7 +339,7 @@ func BlogPostEditSubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to edit blog post")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to edit blog post"))
} }
postUrl := hmnurl.BuildBlogThreadWithPostHash(c.CurrentProject.Slug, cd.ThreadID, postData.Thread.Title, cd.PostID) postUrl := hmnurl.BuildBlogThreadWithPostHash(c.CurrentProject.Slug, cd.ThreadID, postData.Thread.Title, cd.PostID)
@ -385,7 +385,7 @@ func BlogPostReplySubmit(c *RequestContext) ResponseData {
err = c.Req.ParseForm() err = c.Req.ParseForm()
if err != nil { if err != nil {
return ErrorResponse(http.StatusBadRequest, oops.New(nil, "the form data was invalid")) return c.ErrorResponse(http.StatusBadRequest, oops.New(nil, "the form data was invalid"))
} }
unparsed := c.Req.Form.Get("body") unparsed := c.Req.Form.Get("body")
if unparsed == "" { if unparsed == "" {
@ -396,7 +396,7 @@ func BlogPostReplySubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to reply to blog post")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to reply to blog post"))
} }
newPostUrl := hmnurl.BuildBlogPost(c.CurrentProject.Slug, cd.ThreadID, newPostId) newPostUrl := hmnurl.BuildBlogPost(c.CurrentProject.Slug, cd.ThreadID, newPostId)
@ -462,7 +462,7 @@ func BlogPostDeleteSubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete post")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete post"))
} }
if threadDeleted { if threadDeleted {

View File

@ -53,19 +53,19 @@ func DiscordOAuthCallback(c *RequestContext) ResponseData {
code := query.Get("code") code := query.Get("code")
res, err := discord.ExchangeOAuthCode(c.Context(), code, hmnurl.BuildDiscordOAuthCallback()) res, err := discord.ExchangeOAuthCode(c.Context(), code, hmnurl.BuildDiscordOAuthCallback())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to exchange Discord authorization code")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to exchange Discord authorization code"))
} }
expiry := time.Now().Add(time.Duration(res.ExpiresIn) * time.Second) expiry := time.Now().Add(time.Duration(res.ExpiresIn) * time.Second)
user, err := discord.GetCurrentUserAsOAuth(c.Context(), res.AccessToken) user, err := discord.GetCurrentUserAsOAuth(c.Context(), res.AccessToken)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch Discord user info")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch Discord user info"))
} }
// Add the role on Discord // Add the role on Discord
err = discord.AddGuildMemberRole(c.Context(), user.ID, config.Config.Discord.MemberRoleID) err = discord.AddGuildMemberRole(c.Context(), user.ID, config.Config.Discord.MemberRoleID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to add member role")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to add member role"))
} }
// Add the user to our database // Add the user to our database
@ -85,7 +85,7 @@ func DiscordOAuthCallback(c *RequestContext) ResponseData {
c.CurrentUser.ID, c.CurrentUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to save new Discord user info")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to save new Discord user info"))
} }
return c.Redirect(hmnurl.BuildUserSettings("discord"), http.StatusSeeOther) return c.Redirect(hmnurl.BuildUserSettings("discord"), http.StatusSeeOther)
@ -110,7 +110,7 @@ func DiscordUnlink(c *RequestContext) ResponseData {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
return c.Redirect(hmnurl.BuildUserSettings("discord"), http.StatusSeeOther) return c.Redirect(hmnurl.BuildUserSettings("discord"), http.StatusSeeOther)
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get Discord user for unlink")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get Discord user for unlink"))
} }
} }
discordUser := iDiscordUser.(*models.DiscordUser) discordUser := iDiscordUser.(*models.DiscordUser)
@ -123,12 +123,12 @@ func DiscordUnlink(c *RequestContext) ResponseData {
discordUser.ID, discordUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete Discord user")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete Discord user"))
} }
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit Discord user delete")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit Discord user delete"))
} }
err = discord.RemoveGuildMemberRole(c.Context(), discordUser.UserID, config.Config.Discord.MemberRoleID) err = discord.RemoveGuildMemberRole(c.Context(), discordUser.UserID, config.Config.Discord.MemberRoleID)
@ -149,13 +149,13 @@ func DiscordShowcaseBacklog(c *RequestContext) ResponseData {
c.Logger.Warn().Msg("could not do showcase backlog because no discord user exists") c.Logger.Warn().Msg("could not do showcase backlog because no discord user exists")
return c.Redirect(hmnurl.BuildUserProfile(c.CurrentUser.Username), http.StatusSeeOther) return c.Redirect(hmnurl.BuildUserProfile(c.CurrentUser.Username), http.StatusSeeOther)
} else if err != nil { } else if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get discord user")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get discord user"))
} }
duser := iduser.(*models.DiscordUser) duser := iduser.(*models.DiscordUser)
ok, err := discord.AllowedToCreateMessageSnippet(c.Context(), c.Conn, duser.UserID) ok, err := discord.AllowedToCreateMessageSnippet(c.Context(), c.Conn, duser.UserID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if !ok { if !ok {

View File

@ -45,7 +45,7 @@ func Feed(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get count of feed posts")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get count of feed posts"))
} }
numPages := int(math.Ceil(float64(numPosts) / postsPerPage)) numPages := int(math.Ceil(float64(numPosts) / postsPerPage))
@ -87,7 +87,7 @@ func Feed(c *RequestContext) ResponseData {
posts, err := fetchAllPosts(c, lineageBuilder, currentUserId, howManyPostsToSkip, postsPerPage) posts, err := fetchAllPosts(c, lineageBuilder, currentUserId, howManyPostsToSkip, postsPerPage)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
} }
baseData := getBaseData(c) baseData := getBaseData(c)
@ -165,7 +165,7 @@ func AtomFeed(c *RequestContext) ResponseData {
posts, err := fetchAllPosts(c, lineageBuilder, nil, 0, itemsPerFeed) posts, err := fetchAllPosts(c, lineageBuilder, nil, 0, itemsPerFeed)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed posts"))
} }
feedData.Posts = posts feedData.Posts = posts
@ -203,7 +203,7 @@ func AtomFeed(c *RequestContext) ResponseData {
itemsPerFeed, itemsPerFeed,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed projects")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed projects"))
} }
var projectIds []int var projectIds []int
projectMap := make(map[int]int) // map[project id]index in slice projectMap := make(map[int]int) // map[project id]index in slice
@ -235,7 +235,7 @@ func AtomFeed(c *RequestContext) ResponseData {
projectIds, projectIds,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed projects owners")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch feed projects owners"))
} }
for _, res := range owners.ToSlice() { for _, res := range owners.ToSlice() {
owner := res.(*ownerResult) owner := res.(*ownerResult)
@ -277,7 +277,7 @@ func AtomFeed(c *RequestContext) ResponseData {
itemsPerFeed, itemsPerFeed,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets"))
} }
snippetQuerySlice := snippetQueryResult.ToSlice() snippetQuerySlice := snippetQueryResult.ToSlice()
for _, s := range snippetQuerySlice { for _, s := range snippetQuerySlice {

View File

@ -330,7 +330,7 @@ func ForumMarkRead(c *RequestContext) ResponseData {
c.CurrentUser.ID, c.CurrentUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to mark all posts as read")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to mark all posts as read"))
} }
// Delete thread unread info // Delete thread unread info
@ -342,7 +342,7 @@ func ForumMarkRead(c *RequestContext) ResponseData {
c.CurrentUser.ID, c.CurrentUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete thread unread info")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete thread unread info"))
} }
// Delete subforum unread info // Delete subforum unread info
@ -354,7 +354,7 @@ func ForumMarkRead(c *RequestContext) ResponseData {
c.CurrentUser.ID, c.CurrentUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete subforum unread info")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete subforum unread info"))
} }
} else { } else {
c.Perf.StartBlock("SQL", "Update SLRIs") c.Perf.StartBlock("SQL", "Update SLRIs")
@ -373,7 +373,7 @@ func ForumMarkRead(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update forum slris")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update forum slris"))
} }
c.Perf.StartBlock("SQL", "Delete TLRIs") c.Perf.StartBlock("SQL", "Delete TLRIs")
@ -394,13 +394,13 @@ func ForumMarkRead(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete unnecessary tlris")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete unnecessary tlris"))
} }
} }
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit SLRI/TLRI updates")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to commit SLRI/TLRI updates"))
} }
var redirUrl string var redirUrl string
@ -503,7 +503,7 @@ func ForumThread(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update forum tlri")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update forum tlri"))
} }
} }
@ -546,7 +546,7 @@ func ForumPostRedirect(c *RequestContext) ResponseData {
cd.ThreadID, cd.ThreadID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch post ids")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch post ids"))
} }
postQuerySlice := postQueryResult.ToSlice() postQuerySlice := postQueryResult.ToSlice()
c.Perf.EndBlock() c.Perf.EndBlock()
@ -574,7 +574,7 @@ func ForumPostRedirect(c *RequestContext) ResponseData {
cd.ThreadID, cd.ThreadID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch thread title")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch thread title"))
} }
c.Perf.EndBlock() c.Perf.EndBlock()
threadTitle := threadTitleQueryResult.(*threadTitleQuery).ThreadTitle threadTitle := threadTitleQueryResult.(*threadTitleQuery).ThreadTitle
@ -625,7 +625,7 @@ func ForumNewThreadSubmit(c *RequestContext) ResponseData {
err = c.Req.ParseForm() err = c.Req.ParseForm()
if err != nil { if err != nil {
return ErrorResponse(http.StatusBadRequest, oops.New(err, "the form data was invalid")) return c.ErrorResponse(http.StatusBadRequest, oops.New(err, "the form data was invalid"))
} }
title := c.Req.Form.Get("title") title := c.Req.Form.Get("title")
unparsed := c.Req.Form.Get("body") unparsed := c.Req.Form.Get("body")
@ -665,7 +665,7 @@ func ForumNewThreadSubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create new forum thread")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create new forum thread"))
} }
newThreadUrl := hmnurl.BuildForumThread(c.CurrentProject.Slug, cd.LineageBuilder.GetSubforumLineageSlugs(cd.SubforumID), threadId, title, 1) newThreadUrl := hmnurl.BuildForumThread(c.CurrentProject.Slug, cd.LineageBuilder.GetSubforumLineageSlugs(cd.SubforumID), threadId, title, 1)
@ -711,7 +711,7 @@ func ForumPostReplySubmit(c *RequestContext) ResponseData {
err = c.Req.ParseForm() err = c.Req.ParseForm()
if err != nil { if err != nil {
return ErrorResponse(http.StatusBadRequest, oops.New(nil, "the form data was invalid")) return c.ErrorResponse(http.StatusBadRequest, oops.New(nil, "the form data was invalid"))
} }
unparsed := c.Req.Form.Get("body") unparsed := c.Req.Form.Get("body")
if unparsed == "" { if unparsed == "" {
@ -722,7 +722,7 @@ func ForumPostReplySubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to reply to forum post")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to reply to forum post"))
} }
newPostUrl := hmnurl.BuildForumPost(c.CurrentProject.Slug, cd.LineageBuilder.GetSubforumLineageSlugs(cd.SubforumID), cd.ThreadID, newPostId) newPostUrl := hmnurl.BuildForumPost(c.CurrentProject.Slug, cd.LineageBuilder.GetSubforumLineageSlugs(cd.SubforumID), cd.ThreadID, newPostId)
@ -784,7 +784,7 @@ func ForumPostEditSubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to edit forum post")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to edit forum post"))
} }
postUrl := hmnurl.BuildForumPost(c.CurrentProject.Slug, cd.LineageBuilder.GetSubforumLineageSlugs(cd.SubforumID), cd.ThreadID, cd.PostID) postUrl := hmnurl.BuildForumPost(c.CurrentProject.Slug, cd.LineageBuilder.GetSubforumLineageSlugs(cd.SubforumID), cd.ThreadID, cd.PostID)
@ -846,7 +846,7 @@ func ForumPostDeleteSubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete post")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to delete post"))
} }
if threadDeleted { if threadDeleted {

View File

@ -67,7 +67,7 @@ func Index(c *RequestContext) ResponseData {
numProjectsToGet*2, // hedge your bets against projects that don't have any content numProjectsToGet*2, // hedge your bets against projects that don't have any content
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get projects for home page")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get projects for home page"))
} }
defer iterProjects.Close() defer iterProjects.Close()
@ -274,7 +274,7 @@ func Index(c *RequestContext) ResponseData {
models.ThreadTypeProjectBlogPost, models.ThreadTypeProjectBlogPost,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch news post")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch news post"))
} }
newsPostResult := newsPostRow.(*newsPostQuery) newsPostResult := newsPostRow.(*newsPostQuery)
c.Perf.EndBlock() c.Perf.EndBlock()
@ -299,7 +299,7 @@ func Index(c *RequestContext) ResponseData {
`, `,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets"))
} }
snippetQuerySlice := snippetQueryResult.ToSlice() snippetQuerySlice := snippetQueryResult.ToSlice()
showcaseItems := make([]templates.TimelineItem, 0, len(snippetQuerySlice)) showcaseItems := make([]templates.TimelineItem, 0, len(snippetQuerySlice))
@ -343,7 +343,7 @@ func Index(c *RequestContext) ResponseData {
WheelJamUrl: hmnurl.BuildJamIndex(), WheelJamUrl: hmnurl.BuildJamIndex(),
}, c.Perf) }, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render landing page template")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render landing page template"))
} }
return res return res

View File

@ -32,7 +32,7 @@ type PodcastIndexData struct {
func PodcastIndex(c *RequestContext) ResponseData { func PodcastIndex(c *RequestContext) ResponseData {
podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, true, "") podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, true, "")
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if podcastResult.Podcast == nil { if podcastResult.Podcast == nil {
@ -41,7 +41,7 @@ func PodcastIndex(c *RequestContext) ResponseData {
canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID) canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
baseData := getBaseData(c) baseData := getBaseData(c)
@ -63,7 +63,7 @@ func PodcastIndex(c *RequestContext) ResponseData {
var res ResponseData var res ResponseData
err = res.WriteTemplate("podcast_index.html", podcastIndexData, c.Perf) err = res.WriteTemplate("podcast_index.html", podcastIndexData, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast index page")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast index page"))
} }
return res return res
} }
@ -76,12 +76,12 @@ type PodcastEditData struct {
func PodcastEdit(c *RequestContext) ResponseData { func PodcastEdit(c *RequestContext) ResponseData {
podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, false, "") podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, false, "")
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID) canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if podcastResult.Podcast == nil || !canEdit { if podcastResult.Podcast == nil || !canEdit {
@ -99,7 +99,7 @@ func PodcastEdit(c *RequestContext) ResponseData {
var res ResponseData var res ResponseData
err = res.WriteTemplate("podcast_edit.html", podcastEditData, c.Perf) err = res.WriteTemplate("podcast_edit.html", podcastEditData, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast edit page")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast edit page"))
} }
return res return res
} }
@ -107,12 +107,12 @@ func PodcastEdit(c *RequestContext) ResponseData {
func PodcastEditSubmit(c *RequestContext) ResponseData { func PodcastEditSubmit(c *RequestContext) ResponseData {
podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, false, "") podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, false, "")
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID) canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if podcastResult.Podcast == nil || !canEdit { if podcastResult.Podcast == nil || !canEdit {
@ -128,7 +128,7 @@ func PodcastEditSubmit(c *RequestContext) ResponseData {
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
// NOTE(asaf): The error for exceeding the max filesize doesn't have a special type, so we can't easily detect it here. // NOTE(asaf): The error for exceeding the max filesize doesn't have a special type, so we can't easily detect it here.
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to parse form")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to parse form"))
} }
title := c.Req.Form.Get("title") title := c.Req.Form.Get("title")
@ -143,7 +143,7 @@ func PodcastEditSubmit(c *RequestContext) ResponseData {
c.Perf.StartBlock("SQL", "Updating podcast") c.Perf.StartBlock("SQL", "Updating podcast")
tx, err := c.Conn.Begin(c.Context()) tx, err := c.Conn.Begin(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to start db transaction")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to start db transaction"))
} }
defer tx.Rollback(c.Context()) defer tx.Rollback(c.Context())
@ -153,7 +153,7 @@ func PodcastEditSubmit(c *RequestContext) ResponseData {
if errors.As(err, &rejectErr) { if errors.As(err, &rejectErr) {
return RejectRequest(c, rejectErr.Error()) return RejectRequest(c, rejectErr.Error())
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to save podcast image")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to save podcast image"))
} }
} }
@ -173,7 +173,7 @@ func PodcastEditSubmit(c *RequestContext) ResponseData {
podcastResult.Podcast.ID, podcastResult.Podcast.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to update podcast")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to update podcast"))
} }
} else { } else {
_, err = tx.Exec(c.Context(), _, err = tx.Exec(c.Context(),
@ -192,7 +192,7 @@ func PodcastEditSubmit(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to commit db transaction")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to commit db transaction"))
} }
res := c.Redirect(hmnurl.BuildPodcastEdit(c.CurrentProject.Slug), http.StatusSeeOther) res := c.Redirect(hmnurl.BuildPodcastEdit(c.CurrentProject.Slug), http.StatusSeeOther)
@ -212,7 +212,7 @@ func PodcastEpisode(c *RequestContext) ResponseData {
podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, true, episodeGUIDStr) podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, true, episodeGUIDStr)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if podcastResult.Podcast == nil || len(podcastResult.Episodes) == 0 { if podcastResult.Podcast == nil || len(podcastResult.Episodes) == 0 {
@ -246,7 +246,7 @@ func PodcastEpisode(c *RequestContext) ResponseData {
var res ResponseData var res ResponseData
err = res.WriteTemplate("podcast_episode.html", podcastEpisodeData, c.Perf) err = res.WriteTemplate("podcast_episode.html", podcastEpisodeData, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast episode page")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast episode page"))
} }
return res return res
} }
@ -264,12 +264,12 @@ type PodcastEpisodeEditData struct {
func PodcastEpisodeNew(c *RequestContext) ResponseData { func PodcastEpisodeNew(c *RequestContext) ResponseData {
podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, false, "") podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, false, "")
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID) canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if podcastResult.Podcast == nil || !canEdit { if podcastResult.Podcast == nil || !canEdit {
@ -278,7 +278,7 @@ func PodcastEpisodeNew(c *RequestContext) ResponseData {
episodeFiles, err := GetEpisodeFiles(c.CurrentProject.Slug) episodeFiles, err := GetEpisodeFiles(c.CurrentProject.Slug)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to fetch podcast episode file list")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to fetch podcast episode file list"))
} }
podcast := templates.PodcastToTemplate(c.CurrentProject.Slug, podcastResult.Podcast, "") podcast := templates.PodcastToTemplate(c.CurrentProject.Slug, podcastResult.Podcast, "")
@ -291,7 +291,7 @@ func PodcastEpisodeNew(c *RequestContext) ResponseData {
EpisodeFiles: episodeFiles, EpisodeFiles: episodeFiles,
}, c.Perf) }, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast episode new page")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast episode new page"))
} }
return res return res
} }
@ -304,12 +304,12 @@ func PodcastEpisodeEdit(c *RequestContext) ResponseData {
podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, true, episodeGUIDStr) podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, true, episodeGUIDStr)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID) canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if podcastResult.Podcast == nil || len(podcastResult.Episodes) == 0 || !canEdit { if podcastResult.Podcast == nil || len(podcastResult.Episodes) == 0 || !canEdit {
@ -318,7 +318,7 @@ func PodcastEpisodeEdit(c *RequestContext) ResponseData {
episodeFiles, err := GetEpisodeFiles(c.CurrentProject.Slug) episodeFiles, err := GetEpisodeFiles(c.CurrentProject.Slug)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to fetch podcast episode file list")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to fetch podcast episode file list"))
} }
episode := podcastResult.Episodes[0] episode := podcastResult.Episodes[0]
@ -339,7 +339,7 @@ func PodcastEpisodeEdit(c *RequestContext) ResponseData {
var res ResponseData var res ResponseData
err = res.WriteTemplate("podcast_episode_edit.html", podcastEpisodeEditData, c.Perf) err = res.WriteTemplate("podcast_episode_edit.html", podcastEpisodeEditData, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast episode edit page")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast episode edit page"))
} }
return res return res
} }
@ -350,12 +350,12 @@ func PodcastEpisodeSubmit(c *RequestContext) ResponseData {
isEdit := found && episodeGUIDStr != "" isEdit := found && episodeGUIDStr != ""
podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, isEdit, episodeGUIDStr) podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, isEdit, episodeGUIDStr)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID) canEdit, err := CanEditProject(c, c.CurrentUser, podcastResult.Podcast.ProjectID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if podcastResult.Podcast == nil || (isEdit && len(podcastResult.Episodes) == 0) || !canEdit { if podcastResult.Podcast == nil || (isEdit && len(podcastResult.Episodes) == 0) || !canEdit {
@ -366,7 +366,7 @@ func PodcastEpisodeSubmit(c *RequestContext) ResponseData {
episodeFiles, err := GetEpisodeFiles(c.CurrentProject.Slug) episodeFiles, err := GetEpisodeFiles(c.CurrentProject.Slug)
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to fetch podcast episode file list")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to fetch podcast episode file list"))
} }
c.Req.ParseForm() c.Req.ParseForm()
@ -399,7 +399,7 @@ func PodcastEpisodeSubmit(c *RequestContext) ResponseData {
c.Perf.StartBlock("MP3", "Parsing mp3 file for duration") c.Perf.StartBlock("MP3", "Parsing mp3 file for duration")
file, err := os.Open(fmt.Sprintf("public/media/podcast/%s/%s", c.CurrentProject.Slug, episodeFile)) file, err := os.Open(fmt.Sprintf("public/media/podcast/%s/%s", c.CurrentProject.Slug, episodeFile))
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to open podcast file")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to open podcast file"))
} }
mp3Decoder := mp3.NewDecoder(file) mp3Decoder := mp3.NewDecoder(file)
@ -421,7 +421,7 @@ func PodcastEpisodeSubmit(c *RequestContext) ResponseData {
file.Close() file.Close()
c.Perf.EndBlock() c.Perf.EndBlock()
if decodingError != nil { if decodingError != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to decode mp3 file")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to decode mp3 file"))
} }
c.Perf.StartBlock("MARKDOWN", "Parsing description") c.Perf.StartBlock("MARKDOWN", "Parsing description")
@ -455,7 +455,7 @@ func PodcastEpisodeSubmit(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to update podcast episode")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to update podcast episode"))
} }
} else { } else {
guid := uuid.New() guid := uuid.New()
@ -480,7 +480,7 @@ func PodcastEpisodeSubmit(c *RequestContext) ResponseData {
) )
c.Perf.EndBlock() c.Perf.EndBlock()
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to create podcast episode")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to create podcast episode"))
} }
} }
@ -504,7 +504,7 @@ type PodcastRSSData struct {
func PodcastRSS(c *RequestContext) ResponseData { func PodcastRSS(c *RequestContext) ResponseData {
podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, true, "") podcastResult, err := FetchPodcast(c, c.CurrentProject.ID, true, "")
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
if podcastResult.Podcast == nil { if podcastResult.Podcast == nil {
@ -529,7 +529,7 @@ func PodcastRSS(c *RequestContext) ResponseData {
var res ResponseData var res ResponseData
err = res.WriteTemplate("podcast.xml", podcastRSSData, c.Perf) err = res.WriteTemplate("podcast.xml", podcastRSSData, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast RSS")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render podcast RSS"))
} }
return res return res
} }

View File

@ -71,7 +71,7 @@ func ProjectIndex(c *RequestContext) ResponseData {
models.VisibleProjectLifecycles, models.VisibleProjectLifecycles,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch projects")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch projects"))
} }
allProjectsSlice := allProjects.ToSlice() allProjectsSlice := allProjects.ToSlice()
c.Perf.EndBlock() c.Perf.EndBlock()
@ -112,7 +112,7 @@ func ProjectIndex(c *RequestContext) ResponseData {
c.CurrentUser.ID, c.CurrentUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user projects")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user projects"))
} }
for _, project := range userProjectsResult.ToSlice() { for _, project := range userProjectsResult.ToSlice() {
p := project.(*UserProjectQuery).Project p := project.(*UserProjectQuery).Project
@ -244,7 +244,7 @@ func ProjectHomepage(c *RequestContext) ResponseData {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
return FourOhFour(c) return FourOhFour(c)
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project by slug")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project by slug"))
} }
} }
project = &projectQueryResult.(*projectQuery).Project project = &projectQueryResult.(*projectQuery).Project
@ -262,7 +262,7 @@ func ProjectHomepage(c *RequestContext) ResponseData {
owners, err := FetchProjectOwners(c, project.ID) owners, err := FetchProjectOwners(c, project.ID)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, err) return c.ErrorResponse(http.StatusInternalServerError, err)
} }
canView := false canView := false
@ -312,7 +312,7 @@ func ProjectHomepage(c *RequestContext) ResponseData {
project.ID, project.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch screenshots for project")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch screenshots for project"))
} }
c.Perf.EndBlock() c.Perf.EndBlock()
@ -332,7 +332,7 @@ func ProjectHomepage(c *RequestContext) ResponseData {
project.ID, project.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project links")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project links"))
} }
c.Perf.EndBlock() c.Perf.EndBlock()
@ -363,7 +363,7 @@ func ProjectHomepage(c *RequestContext) ResponseData {
maxRecentActivity, maxRecentActivity,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project posts")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch project posts"))
} }
c.Perf.EndBlock() c.Perf.EndBlock()
@ -445,7 +445,7 @@ func ProjectHomepage(c *RequestContext) ResponseData {
var res ResponseData var res ResponseData
err = res.WriteTemplate("project_homepage.html", projectHomepageData, c.Perf) err = res.WriteTemplate("project_homepage.html", projectHomepageData, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render project homepage template")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render project homepage template"))
} }
return res return res
} }

View File

@ -246,6 +246,15 @@ func (c *RequestContext) Redirect(dest string, code int) ResponseData {
return res return res
} }
func (c *RequestContext) ErrorResponse(status int, errs ...error) ResponseData {
res := ResponseData{
StatusCode: status,
Errors: errs,
}
res.MustWriteTemplate("error.html", getBaseData(c), c.Perf)
return res
}
type ResponseData struct { type ResponseData struct {
StatusCode int StatusCode int
Body *bytes.Buffer Body *bytes.Buffer
@ -304,13 +313,6 @@ func (rd *ResponseData) MustWriteTemplate(name string, data interface{}, rp *per
} }
} }
func ErrorResponse(status int, errs ...error) ResponseData {
return ResponseData{
StatusCode: status,
Errors: errs,
}
}
func doRequest(rw http.ResponseWriter, c *RequestContext, h Handler) { func doRequest(rw http.ResponseWriter, c *RequestContext, h Handler) {
defer func() { defer func() {
/* /*
@ -320,6 +322,7 @@ func doRequest(rw http.ResponseWriter, c *RequestContext, h Handler) {
if recovered := recover(); recovered != nil { if recovered := recover(); recovered != nil {
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
logging.LogPanicValue(c.Logger, recovered, "request panicked and was not handled") logging.LogPanicValue(c.Logger, recovered, "request panicked and was not handled")
rw.Write([]byte("There was a problem handling your request.\nPlease notify an admin at team@handmade.network"))
} }
}() }()

View File

@ -38,6 +38,7 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool, pe
defer logPerf() defer logPerf()
defer LogContextErrors(c, &res) defer LogContextErrors(c, &res)
defer MiddlewarePanicCatcher(c, &res)
return h(c) return h(c)
} }
@ -53,6 +54,7 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool, pe
defer logPerf() defer logPerf()
defer LogContextErrors(c, &res) defer LogContextErrors(c, &res)
defer MiddlewarePanicCatcher(c, &res)
defer storeNoticesInCookie(c, &res) defer storeNoticesInCookie(c, &res)
@ -74,6 +76,7 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool, pe
defer logPerf() defer logPerf()
defer LogContextErrors(c, &res) defer LogContextErrors(c, &res)
defer MiddlewarePanicCatcher(c, &res)
defer storeNoticesInCookie(c, &res) defer storeNoticesInCookie(c, &res)
@ -284,6 +287,8 @@ func getBaseData(c *RequestContext) templates.BaseData {
Session: templateSession, Session: templateSession,
Notices: notices, Notices: notices,
ReportIssueMailto: "team@handmade.network",
OpenGraphItems: buildDefaultOpenGraphItems(c.CurrentProject), OpenGraphItems: buildDefaultOpenGraphItems(c.CurrentProject),
IsProjectPage: !c.CurrentProject.IsHMN(), IsProjectPage: !c.CurrentProject.IsHMN(),
@ -355,7 +360,7 @@ func FetchProjectBySlug(ctx context.Context, conn *pgxpool.Pool, slug string) (*
func ProjectCSS(c *RequestContext) ResponseData { func ProjectCSS(c *RequestContext) ResponseData {
color := c.URL().Query().Get("color") color := c.URL().Query().Get("color")
if color == "" { if color == "" {
return ErrorResponse(http.StatusBadRequest, NewSafeError(nil, "You must provide a 'color' parameter.\n")) return c.ErrorResponse(http.StatusBadRequest, NewSafeError(nil, "You must provide a 'color' parameter.\n"))
} }
baseData := getBaseData(c) baseData := getBaseData(c)
@ -386,7 +391,7 @@ func ProjectCSS(c *RequestContext) ResponseData {
res.Header().Add("Content-Type", "text/css") res.Header().Add("Content-Type", "text/css")
err := res.WriteTemplate("project.css", templateData, c.Perf) err := res.WriteTemplate("project.css", templateData, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to generate project CSS")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to generate project CSS"))
} }
return res return res
@ -423,7 +428,7 @@ func RejectRequest(c *RequestContext, reason string) ResponseData {
RejectReason: reason, RejectReason: reason,
}, c.Perf) }, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to render reject template")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "Failed to render reject template"))
} }
return res return res
} }
@ -439,7 +444,7 @@ func LoadCommonWebsiteData(c *RequestContext) (bool, ResponseData) {
dbProject, err := FetchProjectBySlug(c.Context(), c.Conn, slug) dbProject, err := FetchProjectBySlug(c.Context(), c.Conn, slug)
if err != nil { if err != nil {
return false, ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch current project")) return false, c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch current project"))
} }
if dbProject == nil { if dbProject == nil {
return false, c.Redirect(hmnurl.BuildHomepage(), http.StatusSeeOther) return false, c.Redirect(hmnurl.BuildHomepage(), http.StatusSeeOther)
@ -453,7 +458,7 @@ func LoadCommonWebsiteData(c *RequestContext) (bool, ResponseData) {
if err == nil { if err == nil {
user, session, err := getCurrentUserAndSession(c, sessionCookie.Value) user, session, err := getCurrentUserAndSession(c, sessionCookie.Value)
if err != nil { if err != nil {
return false, ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get current user")) return false, c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to get current user"))
} }
c.CurrentUser = user c.CurrentUser = user
@ -539,6 +544,19 @@ func LogContextErrors(c *RequestContext, res *ResponseData) {
} }
} }
func MiddlewarePanicCatcher(c *RequestContext, res *ResponseData) {
if recovered := recover(); recovered != nil {
maybeError, ok := recovered.(*error)
var err error
if ok {
err = *maybeError
} else {
err = oops.New(nil, fmt.Sprintf("Recovered from panic with value: %v", recovered))
}
*res = c.ErrorResponse(http.StatusInternalServerError, err)
}
}
const NoticesCookieName = "hmn_notices" const NoticesCookieName = "hmn_notices"
func getNoticesFromCookie(c *RequestContext) []templates.Notice { func getNoticesFromCookie(c *RequestContext) []templates.Notice {

View File

@ -35,7 +35,7 @@ func TestLogContextErrors(t *testing.T) {
} }
routes.GET(regexp.MustCompile("^/test$"), func(c *RequestContext) ResponseData { routes.GET(regexp.MustCompile("^/test$"), func(c *RequestContext) ResponseData {
return ErrorResponse(http.StatusInternalServerError, err1, err2) return c.ErrorResponse(http.StatusInternalServerError, err1, err2)
}) })
srv := httptest.NewServer(router) srv := httptest.NewServer(router)

View File

@ -36,7 +36,7 @@ func Showcase(c *RequestContext) ResponseData {
`, `,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets"))
} }
snippetQuerySlice := snippetQueryResult.ToSlice() snippetQuerySlice := snippetQueryResult.ToSlice()
showcaseItems := make([]templates.TimelineItem, 0, len(snippetQuerySlice)) showcaseItems := make([]templates.TimelineItem, 0, len(snippetQuerySlice))

View File

@ -53,7 +53,7 @@ func Snippet(c *RequestContext) ResponseData {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
return FourOhFour(c) return FourOhFour(c)
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippet")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippet"))
} }
} }
c.Perf.EndBlock() c.Perf.EndBlock()
@ -111,7 +111,7 @@ func Snippet(c *RequestContext) ResponseData {
Snippet: snippet, Snippet: snippet,
}, c.Perf) }, c.Perf)
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render snippet template")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render snippet template"))
} }
return res return res
} }

View File

@ -59,7 +59,7 @@ func UserProfile(c *RequestContext) ResponseData {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
return FourOhFour(c) return FourOhFour(c)
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user: %s", username)) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user: %s", username))
} }
} }
profileUser = userResult.(*models.User) profileUser = userResult.(*models.User)
@ -80,7 +80,7 @@ func UserProfile(c *RequestContext) ResponseData {
profileUser.ID, profileUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch links for user: %s", username)) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch links for user: %s", username))
} }
userLinksSlice := userLinkQueryResult.ToSlice() userLinksSlice := userLinkQueryResult.ToSlice()
profileUserLinks := make([]templates.Link, 0, len(userLinksSlice)) profileUserLinks := make([]templates.Link, 0, len(userLinksSlice))
@ -108,7 +108,7 @@ func UserProfile(c *RequestContext) ResponseData {
models.VisibleProjectLifecycles, models.VisibleProjectLifecycles,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch projects for user: %s", username)) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch projects for user: %s", username))
} }
projectQuerySlice := projectQueryResult.ToSlice() projectQuerySlice := projectQueryResult.ToSlice()
templateProjects := make([]templates.Project, 0, len(projectQuerySlice)) templateProjects := make([]templates.Project, 0, len(projectQuerySlice))
@ -139,7 +139,7 @@ func UserProfile(c *RequestContext) ResponseData {
models.VisibleProjectLifecycles, models.VisibleProjectLifecycles,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch posts for user: %s", username)) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch posts for user: %s", username))
} }
postQuerySlice := postQueryResult.ToSlice() postQuerySlice := postQueryResult.ToSlice()
c.Perf.EndBlock() c.Perf.EndBlock()
@ -163,7 +163,7 @@ func UserProfile(c *RequestContext) ResponseData {
profileUser.ID, profileUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets for user: %s", username)) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch snippets for user: %s", username))
} }
snippetQuerySlice := snippetQueryResult.ToSlice() snippetQuerySlice := snippetQueryResult.ToSlice()
c.Perf.EndBlock() c.Perf.EndBlock()
@ -272,7 +272,7 @@ func UserSettings(c *RequestContext) ResponseData {
c.CurrentUser.ID, c.CurrentUser.ID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user links")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user links"))
} }
links := ilinks.ToSlice() links := ilinks.ToSlice()
@ -295,7 +295,7 @@ func UserSettings(c *RequestContext) ResponseData {
if errors.Is(err, db.ErrNoMatchingRows) { if errors.Is(err, db.ErrNoMatchingRows) {
// this is fine, but don't fetch any more messages // this is fine, but don't fetch any more messages
} else if err != nil { } else if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user's Discord account")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch user's Discord account"))
} else { } else {
duser := iduser.(*models.DiscordUser) duser := iduser.(*models.DiscordUser)
tmp := templates.DiscordUserToTemplate(duser) tmp := templates.DiscordUserToTemplate(duser)
@ -316,7 +316,7 @@ func UserSettings(c *RequestContext) ResponseData {
config.Config.Discord.ShowcaseChannelID, config.Config.Discord.ShowcaseChannelID,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to check for unsaved user messages")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to check for unsaved user messages"))
} }
} }
@ -402,7 +402,7 @@ func UserSettingsSave(c *RequestContext) ResponseData {
discordDeleteSnippetOnMessageDelete, discordDeleteSnippetOnMessageDelete,
) )
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user"))
} }
// Process links // Process links
@ -460,7 +460,7 @@ func UserSettingsSave(c *RequestContext) ResponseData {
if errors.As(err, &rejectErr) { if errors.As(err, &rejectErr) {
return RejectRequest(c, rejectErr.Error()) return RejectRequest(c, rejectErr.Error())
} else { } else {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to save new avatar")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to save new avatar"))
} }
} }
@ -468,7 +468,7 @@ func UserSettingsSave(c *RequestContext) ResponseData {
err = tx.Commit(c.Context()) err = tx.Commit(c.Context())
if err != nil { if err != nil {
return ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to save user settings")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to save user settings"))
} }
return c.Redirect(hmnurl.BuildUserSettings(""), http.StatusSeeOther) return c.Redirect(hmnurl.BuildUserSettings(""), http.StatusSeeOther)
@ -489,7 +489,7 @@ func updatePassword(c *RequestContext, tx pgx.Tx, old, new, confirm string) *Res
ok, err := auth.CheckPassword(old, oldHashedPassword) ok, err := auth.CheckPassword(old, oldHashedPassword)
if err != nil { if err != nil {
res := ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to check user's password")) res := c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to check user's password"))
return &res return &res
} }
@ -501,7 +501,7 @@ func updatePassword(c *RequestContext, tx pgx.Tx, old, new, confirm string) *Res
newHashedPassword := auth.HashPassword(new) newHashedPassword := auth.HashPassword(new)
err = auth.UpdatePassword(c.Context(), tx, c.CurrentUser.Username, newHashedPassword) err = auth.UpdatePassword(c.Context(), tx, c.CurrentUser.Username, newHashedPassword)
if err != nil { if err != nil {
res := ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update password")) res := c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update password"))
return &res return &res
} }