Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(inbound-filters): Add react-hydration-errors filter #45188

Merged
merged 10 commits into from
Mar 3, 2023
5 changes: 5 additions & 0 deletions src/sentry/api/endpoints/project_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,11 @@ def put(self, request: Request, project) -> Response:
"sentry:reprocessing_active",
bool(options["sentry:reprocessing_active"]),
)
if "filters:react-hydration-errors" in options:
project.update_option(
"filters:react-hydration-errors",
bool(options["filters:react-hydration-errors"]),
)
if "filters:blacklisted_ips" in options:
project.update_option(
"sentry:blacklisted_ips",
Expand Down
1 change: 1 addition & 0 deletions src/sentry/api/serializers/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ def format_options(attrs: defaultdict(dict)):
"sentry:performance_issue_creation_rate"
),
"filters:blacklisted_ips": "\n".join(options.get("sentry:blacklisted_ips", [])),
"filters:react-hydration-errors": bool(options.get("filters:react-hydration-errors", True)),
priscilawebdev marked this conversation as resolved.
Show resolved Hide resolved
f"filters:{FilterTypes.RELEASES}": "\n".join(
options.get(f"sentry:{FilterTypes.RELEASES}", [])
),
Expand Down
1 change: 1 addition & 0 deletions src/sentry/models/options/project_option.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"digests:mail:maximum_delay",
"mail:subject_prefix",
"mail:subject_template",
"filters:react-hydration-errors",
]
)

Expand Down
9 changes: 6 additions & 3 deletions src/sentry/projectoptions/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,18 @@
# Default legacy-browsers filter
register(key="filters:legacy-browsers", epoch_defaults={1: "0"})

# Default legacy-browsers filter
# Default web crawlers filter
register(key="filters:web-crawlers", epoch_defaults={1: "1", 6: "0"})

# Default legacy-browsers filter
# Default browser extensions filter
register(key="filters:browser-extensions", epoch_defaults={1: "0"})

# Default legacy-browsers filter
# Default localhost filter
register(key="filters:localhost", epoch_defaults={1: "0"})

# Default react hydration errors filter
register(key="filters:react-hydration-errors", epoch_defaults={1: "1"})

# Default breakdowns config
register(
key="sentry:breakdowns",
Expand Down
19 changes: 16 additions & 3 deletions src/sentry/relay/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,27 @@ def get_filter_settings(project: Project) -> Mapping[str, Any]:
settings = _load_filter_settings(flt, project)
filter_settings[filter_id] = settings

error_messages: List[str] = []
if features.has("projects:custom-inbound-filters", project):
invalid_releases = project.get_option(f"sentry:{FilterTypes.RELEASES}")
if invalid_releases:
filter_settings["releases"] = {"releases": invalid_releases}

error_messages = project.get_option(f"sentry:{FilterTypes.ERROR_MESSAGES}")
if error_messages:
filter_settings["errorMessages"] = {"patterns": error_messages}
error_messages += project.get_option(f"sentry:{FilterTypes.ERROR_MESSAGES}") or []

enable_react = project.get_option("filters:react-hydration-errors")
if enable_react:
# 418 - Hydration failed because the initial UI does not match what was rendered on the server.
# 419 - The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.
# 422 - There was an error while hydrating this Suspense boundary. Switched to client rendering.
# 423 - There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
# 425 - Text content does not match server-rendered HTML.
error_messages += [
"https://reactjs.org/docs/error-decoder.html?invariant={418,419,422,423,425}"
]

if error_messages:
filter_settings["errorMessages"] = {"patterns": error_messages}

blacklisted_ips = project.get_option("sentry:blacklisted_ips")
if blacklisted_ips:
Expand Down
9 changes: 9 additions & 0 deletions tests/sentry/api/endpoints/test_project_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ def test_options(self):
"sentry:token_header": "*",
"sentry:verify_ssl": False,
"feedback:branding": False,
"filters:react-hydration-errors": True,
}
with self.feature("projects:custom-inbound-filters"):
self.get_success_response(self.org_slug, self.proj_slug, options=options)
Expand Down Expand Up @@ -558,6 +559,7 @@ def test_options(self):
assert AuditLogEntry.objects.filter(
organization=project.organization, event=audit_log.get_event_id("PROJECT_EDIT")
).exists()
assert project.get_option("filters:react-hydration-errors", "1")

def test_bookmarks(self):
self.get_success_response(self.org_slug, self.proj_slug, isBookmarked="false")
Expand Down Expand Up @@ -688,6 +690,13 @@ def test_store_crash_reports_exceeded(self):
assert self.project.get_option("sentry:store_crash_reports") is None
assert b"storeCrashReports" in resp.content

def test_react_hydration_errors(self):
value = False
options = {"filters:react-hydration-errors": value}
resp = self.get_success_response(self.org_slug, self.proj_slug, options=options)
assert self.project.get_option("filters:react-hydration-errors") == value
assert resp.data["options"]["filters:react-hydration-errors"] == value

def test_relay_pii_config(self):
value = '{"applications": {"freeform": []}}'
resp = self.get_success_response(self.org_slug, self.proj_slug, relayPiiConfig=value)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
created: '2023-01-17T00:14:23.253438Z'
created: '2023-03-02T14:24:26.512612Z'
creator: sentry
source: tests/sentry/relay/test_config.py
---
Expand Down Expand Up @@ -82,6 +82,9 @@ config:
- hoholikik.club
- smartlink.cool
- promfflinkdev.com
errorMessages:
patterns:
- https://reactjs.org/docs/error-decoder.html?invariant={418,419,422,423,425}
legacyBrowsers:
isEnabled: false
localhost:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
created: '2023-01-17T00:14:23.169177Z'
created: '2023-03-02T14:24:26.635295Z'
creator: sentry
source: tests/sentry/relay/test_config.py
---
Expand Down Expand Up @@ -82,6 +82,9 @@ config:
- hoholikik.club
- smartlink.cool
- promfflinkdev.com
errorMessages:
patterns:
- https://reactjs.org/docs/error-decoder.html?invariant={418,419,422,423,425}
legacyBrowsers:
isEnabled: false
localhost:
Expand Down
1 change: 1 addition & 0 deletions tests/sentry/relay/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def test_project_config_uses_filter_features(
blacklisted_ips = ["112.69.248.54"]
default_project.update_option("sentry:error_messages", error_messages)
default_project.update_option("sentry:releases", releases)
default_project.update_option("filters:react-hydration-errors", False)

if has_blacklisted_ips:
default_project.update_option("sentry:blacklisted_ips", blacklisted_ips)
Expand Down