From 48dfb6199796462b5fd6d7a30936ca5e332da5a5 Mon Sep 17 00:00:00 2001 From: Asaf Gartner Date: Tue, 25 May 2021 16:48:57 +0300 Subject: [PATCH] Prevent URL construction from crashing in prod --- src/hmnurl/hmnurl.go | 1 + src/hmnurl/hmnurl_test.go | 1 + src/hmnurl/urls.go | 76 +++++++++++++++++++++++++++++++++++++++ src/logging/logging.go | 6 +--- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/src/hmnurl/hmnurl.go b/src/hmnurl/hmnurl.go index 143e542..ced295c 100644 --- a/src/hmnurl/hmnurl.go +++ b/src/hmnurl/hmnurl.go @@ -20,6 +20,7 @@ type Q struct { var baseUrlParsed url.URL var cacheBust string +var isTest bool func init() { SetGlobalBaseUrl(config.Config.BaseUrl) diff --git a/src/hmnurl/hmnurl_test.go b/src/hmnurl/hmnurl_test.go index 2d756d7..bd333fc 100644 --- a/src/hmnurl/hmnurl_test.go +++ b/src/hmnurl/hmnurl_test.go @@ -14,6 +14,7 @@ func TestUrl(t *testing.T) { SetGlobalBaseUrl(config.Config.BaseUrl) }() SetGlobalBaseUrl("http://handmade.test") + isTest = true t.Run("no query", func(t *testing.T) { result := Url("/test/foo", nil) diff --git a/src/hmnurl/urls.go b/src/hmnurl/urls.go index 1c0d275..8a253ba 100644 --- a/src/hmnurl/urls.go +++ b/src/hmnurl/urls.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" + "git.handmade.network/hmn/hmn/src/logging" "git.handmade.network/hmn/hmn/src/oops" ) @@ -24,36 +25,42 @@ func BuildHomepage() string { } func BuildProjectHomepage(projectSlug string) string { + defer CatchPanic() return ProjectUrl("/", nil, projectSlug) } var RegexProjectIndex = regexp.MustCompile("^/projects$") func BuildProjectIndex() string { + defer CatchPanic() return Url("/projects", nil) } var RegexShowcase = regexp.MustCompile("^/showcase$") func BuildShowcase() string { + defer CatchPanic() return Url("/showcase", nil) } var RegexStreams = regexp.MustCompile("^/streams$") func BuildStreams() string { + defer CatchPanic() return Url("/streams", nil) } var RegexSiteMap = regexp.MustCompile("^/sitemap$") func BuildSiteMap() string { + defer CatchPanic() return Url("/sitemap", nil) } var RegexAtomFeed = regexp.MustCompile("^/atom$") func BuildAtomFeed() string { + defer CatchPanic() return Url("/atom", nil) } @@ -62,18 +69,21 @@ func BuildAtomFeed() string { var RegexLoginAction = regexp.MustCompile("^/login$") func BuildLoginAction(redirectTo string) string { + defer CatchPanic() return Url("/login", []Q{{Name: "redirect", Value: redirectTo}}) } var RegexLoginPage = regexp.MustCompile("^/_login$") func BuildLoginPage(redirectTo string) string { + defer CatchPanic() return Url("/_login", []Q{{Name: "redirect", Value: redirectTo}}) } var RegexLogoutAction = regexp.MustCompile("^/logout$") func BuildLogoutAction() string { + defer CatchPanic() return Url("/logout", nil) } @@ -84,42 +94,49 @@ func BuildLogoutAction() string { var RegexManifesto = regexp.MustCompile("^/manifesto$") func BuildManifesto() string { + defer CatchPanic() return Url("/manifesto", nil) } var RegexAbout = regexp.MustCompile("^/about$") func BuildAbout() string { + defer CatchPanic() return Url("/about", nil) } var RegexCodeOfConduct = regexp.MustCompile("^/code-of-conduct$") func BuildCodeOfConduct() string { + defer CatchPanic() return Url("/code-of-conduct", nil) } var RegexCommunicationGuidelines = regexp.MustCompile("^/communication-guidelines$") func BuildCommunicationGuidelines() string { + defer CatchPanic() return Url("/communication-guidelines", nil) } var RegexContactPage = regexp.MustCompile("^/contact$") func BuildContactPage() string { + defer CatchPanic() return Url("/contact", nil) } var RegexMonthlyUpdatePolicy = regexp.MustCompile("^/monthly-update-policy$") func BuildMonthlyUpdatePolicy() string { + defer CatchPanic() return Url("/monthly-update-policy", nil) } var RegexProjectSubmissionGuidelines = regexp.MustCompile("^/project-guidelines$") func BuildProjectSubmissionGuidelines() string { + defer CatchPanic() return Url("/project-guidelines", nil) } @@ -130,6 +147,7 @@ func BuildProjectSubmissionGuidelines() string { var RegexMember = regexp.MustCompile(`^/m/(?P[^/]+)$`) func BuildMember(username string) string { + defer CatchPanic() if len(username) == 0 { panic(oops.New(nil, "Username must not be blank")) } @@ -143,10 +161,12 @@ func BuildMember(username string) string { var RegexFeed = regexp.MustCompile(`^/feed(/(?P.+)?)?$`) func BuildFeed() string { + defer CatchPanic() return Url("/feed", nil) } func BuildFeedWithPage(page int) string { + defer CatchPanic() if page < 1 { panic(oops.New(nil, "Invalid feed page (%d), must be >= 1", page)) } @@ -163,6 +183,7 @@ func BuildFeedWithPage(page int) string { var RegexPodcast = regexp.MustCompile(`^/podcast$`) func BuildPodcast(projectSlug string) string { + defer CatchPanic() return ProjectUrl("/podcast", nil, projectSlug) } @@ -175,6 +196,7 @@ func BuildPodcast(projectSlug string) string { var RegexForumCategory = regexp.MustCompile(`^/forums(/(?P[^\d/]+(/[^\d]+)*))?(/(?P\d+))?$`) func BuildForumCategory(projectSlug string, subforums []string, page int) string { + defer CatchPanic() if page < 1 { panic(oops.New(nil, "Invalid forum thread page (%d), must be >= 1", page)) } @@ -192,6 +214,7 @@ func BuildForumCategory(projectSlug string, subforums []string, page int) string var RegexForumNewThread = regexp.MustCompile(`^/forums(/(?P[^\d/]+(/[^\d]+)*))?/new?$`) func BuildForumNewThread(projectSlug string, subforums []string) string { + defer CatchPanic() builder := buildForumCategoryPath(subforums) builder.WriteString("/new") @@ -201,12 +224,14 @@ func BuildForumNewThread(projectSlug string, subforums []string) string { var RegexForumThread = regexp.MustCompile(`^/forums(/(?P[^\d/]+(/[^\d]+)*))?/t/(?P\d+)(-([^/]+))?(/(?P\d+))?$`) func BuildForumThread(projectSlug string, subforums []string, threadId int, title string, page int) string { + defer CatchPanic() builder := buildForumThreadPath(subforums, threadId, title, page) return ProjectUrl(builder.String(), nil, projectSlug) } func BuildForumThreadWithPostHash(projectSlug string, subforums []string, threadId int, title string, page int, postId int) string { + defer CatchPanic() builder := buildForumThreadPath(subforums, threadId, title, page) return ProjectUrlWithFragment(builder.String(), nil, projectSlug, strconv.Itoa(postId)) @@ -215,6 +240,7 @@ func BuildForumThreadWithPostHash(projectSlug string, subforums []string, thread var RegexForumPost = regexp.MustCompile(`^/forums(/(?P[^\d/]+(/[^\d]+)*))?/t/(?P\d+)/p/(?P\d+)$`) func BuildForumPost(projectSlug string, subforums []string, threadId int, postId int) string { + defer CatchPanic() builder := buildForumPostPath(subforums, threadId, postId) return ProjectUrl(builder.String(), nil, projectSlug) @@ -223,6 +249,7 @@ func BuildForumPost(projectSlug string, subforums []string, threadId int, postId var RegexForumPostDelete = regexp.MustCompile(`^/forums(/(?P[^\d/]+(/[^\d]+)*))?/t/(?P\d+)/p/(?P\d+)/delete$`) func BuildForumPostDelete(projectSlug string, subforums []string, threadId int, postId int) string { + defer CatchPanic() builder := buildForumPostPath(subforums, threadId, postId) builder.WriteString("/delete") return ProjectUrl(builder.String(), nil, projectSlug) @@ -231,6 +258,7 @@ func BuildForumPostDelete(projectSlug string, subforums []string, threadId int, var RegexForumPostEdit = regexp.MustCompile(`^/forums(/(?P[^\d/]+(/[^\d]+)*))?/t/(?P\d+)/p/(?P\d+)/edit$`) func BuildForumPostEdit(projectSlug string, subforums []string, threadId int, postId int) string { + defer CatchPanic() builder := buildForumPostPath(subforums, threadId, postId) builder.WriteString("/edit") return ProjectUrl(builder.String(), nil, projectSlug) @@ -240,6 +268,7 @@ var RegexForumPostReply = regexp.MustCompile(`^/forums(/(?P[^\d/]+(/[^\d]+ // TODO: It's kinda weird that we have "replies" to a specific post. That's not how the data works. I guess this just affects what you see as the "post you're replying to" on the post composer page? func BuildForumPostReply(projectSlug string, subforums []string, threadId int, postId int) string { + defer CatchPanic() builder := buildForumPostPath(subforums, threadId, postId) builder.WriteString("/reply") return ProjectUrl(builder.String(), nil, projectSlug) @@ -248,6 +277,7 @@ func BuildForumPostReply(projectSlug string, subforums []string, threadId int, p var RegexForumPostQuote = regexp.MustCompile(`^/forums(/(?P[^\d/]+(/[^\d]+)*))?/t/(?P\d+)/p/(?P\d+)/quote$`) func BuildForumPostQuote(projectSlug string, subforums []string, threadId int, postId int) string { + defer CatchPanic() builder := buildForumPostPath(subforums, threadId, postId) builder.WriteString("/quote") return ProjectUrl(builder.String(), nil, projectSlug) @@ -262,6 +292,7 @@ var RegexBlogsRedirect = regexp.MustCompile(`^/blogs`) var RegexBlog = regexp.MustCompile(`^/blog(/(?P\d+))?$`) func BuildBlog(projectSlug string, page int) string { + defer CatchPanic() if page < 1 { panic(oops.New(nil, "Invalid blog page (%d), must be >= 1", page)) } @@ -277,11 +308,13 @@ func BuildBlog(projectSlug string, page int) string { var RegexBlogThread = regexp.MustCompile(`^/blog/p/(?P\d+)(-([^/]+))?(/(?P\d+))?$`) func BuildBlogThread(projectSlug string, threadId int, title string, page int) string { + defer CatchPanic() builder := buildBlogThreadPath(threadId, title, page) return ProjectUrl(builder.String(), nil, projectSlug) } func BuildBlogThreadWithPostHash(projectSlug string, threadId int, title string, page int, postId int) string { + defer CatchPanic() builder := buildBlogThreadPath(threadId, title, page) return ProjectUrlWithFragment(builder.String(), nil, projectSlug, strconv.Itoa(postId)) } @@ -289,6 +322,7 @@ func BuildBlogThreadWithPostHash(projectSlug string, threadId int, title string, var RegexBlogPost = regexp.MustCompile(`^/blog/p/(?P\d+)/e/(?P\d+)$`) func BuildBlogPost(projectSlug string, threadId int, postId int) string { + defer CatchPanic() builder := buildBlogPostPath(threadId, postId) return ProjectUrl(builder.String(), nil, projectSlug) } @@ -296,6 +330,7 @@ func BuildBlogPost(projectSlug string, threadId int, postId int) string { var RegexBlogPostDelete = regexp.MustCompile(`^/blog/p/(?P\d+)/e/(?P\d+)/delete$`) func BuildBlogPostDelete(projectSlug string, threadId int, postId int) string { + defer CatchPanic() builder := buildBlogPostPath(threadId, postId) builder.WriteString("/delete") return ProjectUrl(builder.String(), nil, projectSlug) @@ -304,6 +339,7 @@ func BuildBlogPostDelete(projectSlug string, threadId int, postId int) string { var RegexBlogPostEdit = regexp.MustCompile(`^/blog/p/(?P\d+)/e/(?P\d+)/edit$`) func BuildBlogPostEdit(projectSlug string, threadId int, postId int) string { + defer CatchPanic() builder := buildBlogPostPath(threadId, postId) builder.WriteString("/edit") return ProjectUrl(builder.String(), nil, projectSlug) @@ -312,6 +348,7 @@ func BuildBlogPostEdit(projectSlug string, threadId int, postId int) string { var RegexBlogPostReply = regexp.MustCompile(`^/blog/p/(?P\d+)/e/(?P\d+)/reply$`) func BuildBlogPostReply(projectSlug string, threadId int, postId int) string { + defer CatchPanic() builder := buildBlogPostPath(threadId, postId) builder.WriteString("/reply") return ProjectUrl(builder.String(), nil, projectSlug) @@ -320,6 +357,7 @@ func BuildBlogPostReply(projectSlug string, threadId int, postId int) string { var RegexBlogPostQuote = regexp.MustCompile(`^/blog/p/(?P\d+)/e/(?P\d+)/quote$`) func BuildBlogPostQuote(projectSlug string, threadId int, postId int) string { + defer CatchPanic() builder := buildBlogPostPath(threadId, postId) builder.WriteString("/quote") return ProjectUrl(builder.String(), nil, projectSlug) @@ -332,24 +370,28 @@ func BuildBlogPostQuote(projectSlug string, threadId int, postId int) string { var RegexWiki = regexp.MustCompile(`^/wiki$`) func BuildWiki(projectSlug string) string { + defer CatchPanic() return ProjectUrl("/wiki", nil, projectSlug) } var RegexWikiIndex = regexp.MustCompile(`^/wiki/index$`) func BuildWikiIndex(projectSlug string) string { + defer CatchPanic() return ProjectUrl("/wiki/index", nil, projectSlug) } var RegexWikiArticle = regexp.MustCompile(`^/wiki/(?P\d+)(-([^/])+)?$`) func BuildWikiArticle(projectSlug string, articleId int, title string) string { + defer CatchPanic() builder := buildWikiArticlePath(articleId, title) return ProjectUrl(builder.String(), nil, projectSlug) } func BuildWikiArticleWithSectionName(projectSlug string, articleId int, title string, sectionName string) string { + defer CatchPanic() builder := buildWikiArticlePath(articleId, title) return ProjectUrlWithFragment(builder.String(), nil, projectSlug, sectionName) @@ -358,6 +400,7 @@ func BuildWikiArticleWithSectionName(projectSlug string, articleId int, title st var RegexWikiArticleEdit = regexp.MustCompile(`^/wiki/(?P\d+)/edit$`) func BuildWikiArticleEdit(projectSlug string, articleId int) string { + defer CatchPanic() builder := buildWikiArticlePath(articleId, "") builder.WriteString("/edit") @@ -367,6 +410,7 @@ func BuildWikiArticleEdit(projectSlug string, articleId int) string { var RegexWikiArticleDelete = regexp.MustCompile(`^/wiki/(?P\d+)/delete$`) func BuildWikiArticleDelete(projectSlug string, articleId int) string { + defer CatchPanic() builder := buildWikiArticlePath(articleId, "") builder.WriteString("/delete") @@ -376,6 +420,7 @@ func BuildWikiArticleDelete(projectSlug string, articleId int) string { var RegexWikiArticleHistory = regexp.MustCompile(`^/wiki/(?P\d+)(-([^/])+)?/history$`) func BuildWikiArticleHistory(projectSlug string, articleId int, title string) string { + defer CatchPanic() builder := buildWikiArticlePath(articleId, title) builder.WriteString("/history") @@ -385,6 +430,7 @@ func BuildWikiArticleHistory(projectSlug string, articleId int, title string) st var RegexWikiTalk = regexp.MustCompile(`^/wiki/(?P\d+)(-([^/])+)?/talk$`) func BuildWikiTalk(projectSlug string, articleId int, title string) string { + defer CatchPanic() builder := buildWikiArticlePath(articleId, title) builder.WriteString("/talk") @@ -394,6 +440,7 @@ func BuildWikiTalk(projectSlug string, articleId int, title string) string { var RegexWikiRevision = regexp.MustCompile(`^/wiki/(?P\d+)(-([^/])+)?/(?P\d+)$`) func BuildWikiRevision(projectSlug string, articleId int, title string, revisionId int) string { + defer CatchPanic() if revisionId < 1 { panic(oops.New(nil, "Invalid wiki revision id (%d), must be >= 1", revisionId)) } @@ -407,6 +454,7 @@ func BuildWikiRevision(projectSlug string, articleId int, title string, revision var RegexWikiDiff = regexp.MustCompile(`^/wiki/(?P\d+)(-([^/])+)?/diff/(?P\d+)/(?P\d+)$`) func BuildWikiDiff(projectSlug string, articleId int, title string, revisionIdOld int, revisionIdNew int) string { + defer CatchPanic() if revisionIdOld < 1 { panic(oops.New(nil, "Invalid wiki revision id (%d), must be >= 1", revisionIdOld)) } @@ -426,6 +474,7 @@ func BuildWikiDiff(projectSlug string, articleId int, title string, revisionIdOl var RegexWikiTalkPost = regexp.MustCompile(`^/wiki/(?P\d+)/talk/(?P\d+)$`) func BuildWikiTalkPost(projectSlug string, articleId int, postId int) string { + defer CatchPanic() builder := buildWikiTalkPath(articleId, postId) return ProjectUrl(builder.String(), nil, projectSlug) @@ -434,6 +483,7 @@ func BuildWikiTalkPost(projectSlug string, articleId int, postId int) string { var RegexWikiTalkPostDelete = regexp.MustCompile(`^/wiki/(?P\d+)/talk/(?P\d+)/delete$`) func BuildWikiTalkPostDelete(projectSlug string, articleId int, postId int) string { + defer CatchPanic() builder := buildWikiTalkPath(articleId, postId) builder.WriteString("/delete") @@ -443,6 +493,7 @@ func BuildWikiTalkPostDelete(projectSlug string, articleId int, postId int) stri var RegexWikiTalkPostEdit = regexp.MustCompile(`^/wiki/(?P\d+)/talk/(?P\d+)/edit$`) func BuildWikiTalkPostEdit(projectSlug string, articleId int, postId int) string { + defer CatchPanic() builder := buildWikiTalkPath(articleId, postId) builder.WriteString("/edit") @@ -452,6 +503,7 @@ func BuildWikiTalkPostEdit(projectSlug string, articleId int, postId int) string var RegexWikiTalkPostReply = regexp.MustCompile(`^/wiki/(?P\d+)/talk/(?P\d+)/reply$`) func BuildWikiTalkPostReply(projectSlug string, articleId int, postId int) string { + defer CatchPanic() builder := buildWikiTalkPath(articleId, postId) builder.WriteString("/reply") @@ -461,6 +513,7 @@ func BuildWikiTalkPostReply(projectSlug string, articleId int, postId int) strin var RegexWikiTalkPostQuote = regexp.MustCompile(`^/wiki/(?P\d+)/talk/(?P\d+)/quote$`) func BuildWikiTalkPostQuote(projectSlug string, articleId int, postId int) string { + defer CatchPanic() builder := buildWikiTalkPath(articleId, postId) builder.WriteString("/quote") @@ -474,18 +527,21 @@ func BuildWikiTalkPostQuote(projectSlug string, articleId int, postId int) strin var RegexLibrary = regexp.MustCompile(`^/library$`) func BuildLibrary(projectSlug string) string { + defer CatchPanic() return ProjectUrl("/library", nil, projectSlug) } var RegexLibraryAll = regexp.MustCompile(`^/library/all$`) func BuildLibraryAll(projectSlug string) string { + defer CatchPanic() return ProjectUrl("/library/all", nil, projectSlug) } var RegexLibraryTopic = regexp.MustCompile(`^/library/topic/(?P\d+)$`) func BuildLibraryTopic(projectSlug string, topicId int) string { + defer CatchPanic() if topicId < 1 { panic(oops.New(nil, "Invalid library topic ID (%d), must be >= 1", topicId)) } @@ -500,6 +556,7 @@ func BuildLibraryTopic(projectSlug string, topicId int) string { var RegexLibraryResource = regexp.MustCompile(`^/library/resource/(?P\d+)$`) func BuildLibraryResource(projectSlug string, resourceId int) string { + defer CatchPanic() builder := buildLibraryResourcePath(resourceId) return ProjectUrl(builder.String(), nil, projectSlug) @@ -508,12 +565,14 @@ func BuildLibraryResource(projectSlug string, resourceId int) string { var RegexLibraryDiscussion = regexp.MustCompile(`^/library/resource/(?P\d+)/d/(?P\d+)(/(?P\d+))?$`) func BuildLibraryDiscussion(projectSlug string, resourceId int, threadId int, page int) string { + defer CatchPanic() builder := buildLibraryDiscussionPath(resourceId, threadId, page) return ProjectUrl(builder.String(), nil, projectSlug) } func BuildLibraryDiscussionWithPostHash(projectSlug string, resourceId int, threadId int, page int, postId int) string { + defer CatchPanic() if postId < 1 { panic(oops.New(nil, "Invalid library post ID (%d), must be >= 1", postId)) } @@ -525,6 +584,7 @@ func BuildLibraryDiscussionWithPostHash(projectSlug string, resourceId int, thre var RegexLibraryPost = regexp.MustCompile(`^/library/resource/(?P\d+)/d/(?P\d+)/p/(?P\d+)$`) func BuildLibraryPost(projectSlug string, resourceId int, threadId int, postId int) string { + defer CatchPanic() builder := buildLibraryPostPath(resourceId, threadId, postId) return ProjectUrl(builder.String(), nil, projectSlug) @@ -533,6 +593,7 @@ func BuildLibraryPost(projectSlug string, resourceId int, threadId int, postId i var RegexLibraryPostDelete = regexp.MustCompile(`^/library/resource/(?P\d+)/d/(?P\d+)/p/(?P\d+)/delete$`) func BuildLibraryPostDelete(projectSlug string, resourceId int, threadId int, postId int) string { + defer CatchPanic() builder := buildLibraryPostPath(resourceId, threadId, postId) builder.WriteString("/delete") @@ -542,6 +603,7 @@ func BuildLibraryPostDelete(projectSlug string, resourceId int, threadId int, po var RegexLibraryPostEdit = regexp.MustCompile(`^/library/resource/(?P\d+)/d/(?P\d+)/p/(?P\d+)/edit$`) func BuildLibraryPostEdit(projectSlug string, resourceId int, threadId int, postId int) string { + defer CatchPanic() builder := buildLibraryPostPath(resourceId, threadId, postId) builder.WriteString("/edit") @@ -551,6 +613,7 @@ func BuildLibraryPostEdit(projectSlug string, resourceId int, threadId int, post var RegexLibraryPostReply = regexp.MustCompile(`^/library/resource/(?P\d+)/d/(?P\d+)/p/(?P\d+)/reply$`) func BuildLibraryPostReply(projectSlug string, resourceId int, threadId int, postId int) string { + defer CatchPanic() builder := buildLibraryPostPath(resourceId, threadId, postId) builder.WriteString("/reply") @@ -560,6 +623,7 @@ func BuildLibraryPostReply(projectSlug string, resourceId int, threadId int, pos var RegexLibraryPostQuote = regexp.MustCompile(`^/library/resource/(?P\d+)/d/(?P\d+)/p/(?P\d+)/quote$`) func BuildLibraryPostQuote(projectSlug string, resourceId int, threadId int, postId int) string { + defer CatchPanic() builder := buildLibraryPostPath(resourceId, threadId, postId) builder.WriteString("/quote") @@ -573,12 +637,14 @@ func BuildLibraryPostQuote(projectSlug string, resourceId int, threadId int, pos var RegexProjectCSS = regexp.MustCompile("^/assets/project.css$") func BuildProjectCSS(color string) string { + defer CatchPanic() return Url("/assets/project.css", []Q{{"color", color}}) } var RegexPublic = regexp.MustCompile("^/public/.+$") func BuildPublic(filepath string, cachebust bool) string { + defer CatchPanic() filepath = strings.Trim(filepath, "/") if len(strings.TrimSpace(filepath)) == 0 { panic(oops.New(nil, "Attempted to build a /public url with no path")) @@ -605,6 +671,7 @@ func BuildPublic(filepath string, cachebust bool) string { } func BuildTheme(filepath string, theme string, cachebust bool) string { + defer CatchPanic() if len(theme) == 0 { panic(oops.New(nil, "Theme can't be blank")) } @@ -619,6 +686,7 @@ var RegexMarkRead = regexp.MustCompile(`^/_markread/(?P\d+)$`) // NOTE(asaf): categoryId == 0 means ALL CATEGORIES func BuildMarkRead(categoryId int) string { + defer CatchPanic() if categoryId < 0 { panic(oops.New(nil, "Invalid category ID (%d), must be >= 0", categoryId)) } @@ -827,3 +895,11 @@ func PathSafeTitle(title string) string { title = url.PathEscape(title) return title } + +func CatchPanic() { + if !isTest { + if recovered := recover(); recovered != nil { + logging.LogPanicValue(nil, recovered, "Url construction failed") + } + } +} diff --git a/src/logging/logging.go b/src/logging/logging.go index 3561b43..8b1ed9b 100644 --- a/src/logging/logging.go +++ b/src/logging/logging.go @@ -195,11 +195,7 @@ func LogPanicValue(logger *zerolog.Logger, val interface{}, msg string) { } if err, ok := val.(error); ok { - l := logger.Error().Err(err) - if _, ok := err.(*oops.Error); !ok { - l = l.Interface(zerolog.ErrorStackFieldName, oops.Trace()) - } - l.Msg(msg) + logger.Error().Stack().Err(err).Msg(msg) } else { logger.Error(). Interface("recovered", val).