Fix browser freezing when PostgreSQL decides not to highlight any matches
Closes #386 (closed) .
Frontend entered an infinite loop in MarkdownText.addMarks when PostgreSQL
decides to return search results from ts_query but doesn't highlight them
when requesting ts_headline with the same query. This seems to happen on
staging/prod databases and could not be replicated locally even when all
data was copied, which leads me to believe it's a locale issue (my laptop
is en_US for reference).
Example backend -> frontend response when searching for "bg" (see the "highlighted_words" field)
On staging/prod:
{
"text": "I'm not sure if 1 is correct. If we look at the linearity property of Fourier: For any complex numbers a and b, if h(x) = af(x) + bg(x), then \u0125(\u03be) = a \u00b7 f\u0302(\u03be) + b \u00b7 \u011d(\u03be). So it should be 2 \u00b7 F(u,v) and not 2 \u2217 F(u,v).\r\nAnd if we look at 2 as a constant function, then the DFT of c(x) = 2 isn't 2 but the dirac-delta impulse at 2. So this still doesn't make sense.",
"long_id": "85iheehpj8j2ax5g",
"rank": 0.06079271,
"author_username": "barlasa",
"author_displayname": "Ayseg\u00fcl Barlas",
"highlighted_words": [
"bg"
],
"answer_long_id": "5c1d583729082200e37306e3",
"exam_displayname": "FS10",
"filename": "bdubehxd.pdf",
"category_displayname": "Visual Computing",
"category_slug": "VisualComputing",
"type": "comment"
},
{
"text": "sch\u00e9in Schr\u00ebft\u00a0bg. ",
"long_id": "m9sxb0sowgsm9tgj",
"rank": 0.06079271,
"author_username": "caoral",
"author_displayname": "Cagri Oral",
"highlighted_words": [],
"answer_long_id": "wtno55y3wkl0bh4l",
"exam_displayname": "FS21",
"filename": "4pft8mxl.pdf",
"category_displayname": "Lineare Algebra",
"category_slug": "LineareAlgebra",
"type": "comment"
}
On my local machine:
{
"text": "I'm not sure if 1 is correct. If we look at the linearity property of Fourier: For any complex numbers a and b, if h(x) = af(x) + bg(x), then \u0125(\u03be) = a \u00b7 f\u0302(\u03be) + b \u00b7 \u011d(\u03be). So it should be 2 \u00b7 F(u,v) and not 2 \u2217 F(u,v).\r\nAnd if we look at 2 as a constant function, then the DFT of c(x) = 2 isn't 2 but the dirac-delta impulse at 2. So this still doesn't make sense.",
"long_id": "85iheehpj8j2ax5g",
"rank": 0.06079271,
"author_username": "barlasa",
"author_displayname": "Ayseg\u00fcl Barlas",
"highlighted_words": [
"bg"
],
"answer_long_id": "5c1d583729082200e37306e3",
"exam_displayname": "FS10",
"filename": "bdubehxd.pdf",
"category_displayname": "Visual Computing",
"category_slug": "VisualComputing",
"type": "comment"
},
{
"text": "sch\u00e9in Schr\u00ebft\u00a0bg. ",
"long_id": "m9sxb0sowgsm9tgj",
"rank": 0.06079271,
"author_username": "caoral",
"author_displayname": "Cagri Oral",
"highlighted_words": [
"bg"
],
"answer_long_id": "wtno55y3wkl0bh4l",
"exam_displayname": "FS21",
"filename": "4pft8mxl.pdf",
"category_displayname": "Lineare Algebra",
"category_slug": "LineareAlgebra",
"type": "comment"
}
answer/comment.highlighted_words from the backend is passed as
addMarks(obj, new RegExp(highlighted_words.join("|"))). But when the
array is empty, the RegExp is instantiated as new RegExp(""). This
instance matches all inputs, even the empty string. So string.match(regex)
returns a match with 0 length, causing the while loop within addMarks to loop forever.
This never happened on the old search page (and only happens on QuickSearch)
since the old search page uses a wrapper component HighlightedMarkdown
that checks for this exact case....
We fix the problem and prevent it in the future by:
- Inside
addMarks(), if anyone accidentally does the same mistake in the future, check if the RegExp is empty and return early. - Merge the functionality of
HighlightedMarkdown(only used in 1 other place) intoMarkdownText, which prevents developers from passing raw RegEx. They must now pass an array of words to highlight, which can now safely by empty or undefined.