Handle removing last word of empty text

Sooo, I added this more graceful regex and error logging… then realized that this shouldn't be happening in the first place, because we should only be removing the last word of the query if you picked the filter via typing, not advanced search!

I'm glad to have the assertion error and the new handler, but I'll fix the cause too in the next change :p
This commit is contained in:
Emi Matchu 2021-01-22 14:12:07 -08:00
parent 4c0afae38e
commit a527d44e12
2 changed files with 37 additions and 4 deletions

View file

@ -22,6 +22,7 @@ import { ClassNames } from "@emotion/react";
import Autosuggest from "react-autosuggest";
import useCurrentUser from "../components/useCurrentUser";
import { logAndCapture } from "../util";
export const emptySearchQuery = {
value: "",
@ -192,12 +193,9 @@ function SearchToolbar({
}
}}
onSuggestionSelected={(e, { suggestion }) => {
const valueWithoutLastWord = query.value
? query.value.match(/^(.*?)\s*\S+$/)[1]
: query.value;
onChange({
...query,
value: valueWithoutLastWord,
value: removeLastWord(query.value),
filterToZoneLabel: suggestion.zoneLabel || query.filterToZoneLabel,
filterToItemKind: suggestion.itemKind || query.filterToItemKind,
filterToCurrentUserOwnsOrWants:
@ -425,4 +423,27 @@ function pluralizeZoneLabel(zoneLabel) {
}
}
/**
* removeLastWord returns a copy of the text, with the last word and any
* preceding space removed.
*/
function removeLastWord(text) {
// This regex matches the full text, and assigns the last word and any
// preceding text to subgroup 2, and all preceding text to subgroup 1. If
// there's no last word, we'll still match, and the full string will be in
// subgroup 1, including any space - no changes made!
const match = text.match(/^(.*?)(\s*\S+)?$/);
if (!match) {
logAndCapture(
new Error(
`Assertion failure: pattern should match any input text, ` +
`but failed to match ${JSON.stringify(text)}`
)
);
return text;
}
return match[1];
}
export default SearchToolbar;

View file

@ -1,6 +1,7 @@
import React from "react";
import { Box, Heading, useColorModeValue } from "@chakra-ui/react";
import loadableLibrary from "@loadable/component";
import * as Sentry from "@sentry/react";
/**
* Delay hides its content at first, then shows it after the given delay.
@ -317,3 +318,14 @@ export function loadable(load, options) {
options
);
}
/**
* logAndCapture will print an error to the console, and send it to Sentry.
*
* This is useful when there's a graceful recovery path, but it's still a
* genuinely unexpected error worth logging.
*/
export function logAndCapture(e) {
console.error(e);
Sentry.captureException(e);
}