Skip to content

fix: create placeholder metrics for failed legacy->cloud translations#15

Merged
janmatzek merged 2 commits into
gooddata:masterfrom
janmatzek:jmat/SVS-1335-metrics-migration-omits-to-create-metrics-in-cloud-it-does-not-create-error-sqrt-1-placeholder-for-some-cases-with-computed-attributes
Jul 3, 2026
Merged

fix: create placeholder metrics for failed legacy->cloud translations#15
janmatzek merged 2 commits into
gooddata:masterfrom
janmatzek:jmat/SVS-1335-metrics-migration-omits-to-create-metrics-in-cloud-it-does-not-create-error-sqrt-1-placeholder-for-some-cases-with-computed-attributes

Conversation

@janmatzek

@janmatzek janmatzek commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

JIRA: SVS-1335

Summary by CodeRabbit

  • New Features
    • Metrics that fail MAQL transformation now receive a safe placeholder MAQL (SELECT SQRT(-1)) so migration can proceed.
    • Failed metrics are labeled with ERROR and a [ERROR] title prefix, with the error details embedded in the placeholder.
  • Bug Fixes
    • Improved error-first handling for transformation failures and unresolved identifiers.
  • Tests
    • Added unit tests for placeholder generation and error handling, and expanded fixtures for unresolved identifiers and failed MAQL cases.
  • Documentation
    • Updated coding standards header to use a {year} placeholder.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4caadb61-d245-4495-b03c-0c74d0cb2db1

📥 Commits

Reviewing files that changed from the base of the PR and between fa75f62 and 0619715.

📒 Files selected for processing (1)
  • .claude/rules/coding_standards.md
✅ Files skipped from review due to trivial changes (1)
  • .claude/rules/coding_standards.md

📝 Walkthrough

Walkthrough

Metrics migration now recovers from MAQL transformation failures by generating placeholder MAQL, tagging affected metrics as errors, and adding tests and fixtures for an unresolved-identifier case. The coding standards header also now uses a year placeholder.

Changes

Placeholder MAQL error handling

Layer / File(s) Summary
build_placeholder_maql helper and disable_broken_metric refactor
src/gooddata_legacy2cloud/metrics/utils.py
comment_out_lines becomes public; build_placeholder_maql centralizes commented MAQL, broken-metric comment adjustment, optional error text, and SELECT SQRT(-1); disable_broken_metric now parses error_response and delegates placeholder generation.
CloudMetric error-first transformation handling
src/gooddata_legacy2cloud/metrics/cloud_metric.py
Imports build_placeholder_maql; adds has_error; _get_cloud_maql catches transformation exceptions to build placeholder MAQL and log instead of raising; get() now applies "ERROR" tagging and "[ERROR]" titles before the warning path.
Unit tests and fixtures for placeholder MAQL and error metrics
tests/test_metrics_utils.py, tests/test_metrics.py, tests/data/metrics/legacy_objects/objects_by_uri.json, tests/data/metrics/test_cases/with_unresolved_identifier_*.json
Adds tests for comment_out_lines, build_placeholder_maql, and disable_broken_metric; adds legacy/cloud fixtures for an unresolved identifier metric and includes the new migration case.
Header year placeholder
.claude/rules/coding_standards.md
Replaces the fixed copyright year in the file header with {year}.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: xvalovic

Poem

A rabbit hopped through metric mist,
With SQRT(-1) tucked in its list.
When MAQL went sideways, no crash did bloom,
Just [ERROR] tags and a placeholder room.
Thump thump, the fixtures all passed!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: creating placeholder metrics when legacy-to-cloud MAQL translation fails.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/gooddata_legacy2cloud/metrics/utils.py (1)

44-59: 📐 Maintainability & Code Quality | 🔵 Trivial

Docstring missing Args/Returns sections.

build_placeholder_maql is a new public helper (used cross-module by cloud_metric.py) but its docstring omits the Args/Returns sections mandated for public APIs.

📝 Suggested docstring
     """
-    Comments out the original MAQL, optionally appends a labeled note, and adds a
-    SQRT(-1) placeholder expression so the metric can still be created in Cloud.
+    Comments out the original MAQL, optionally appends a labeled note, and adds a
+    SQRT(-1) placeholder expression so the metric can still be created in Cloud.
+
+    Args:
+        original_maql: The Legacy MAQL expression that could not be translated.
+        extra_message: Optional additional note (e.g. exception text) to include.
+        error_label: Label to prefix `extra_message` with. Ignored if falsy.
+
+    Returns:
+        The commented-out placeholder MAQL string.
     """

As per coding guidelines, "Public APIs (entry points and Builder methods) must use Google-style docstrings with Args, Returns, and Raises sections."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/gooddata_legacy2cloud/metrics/utils.py` around lines 44 - 59, The public
helper build_placeholder_maql is missing the required Google-style docstring
sections. Update its docstring in utils.py to include clear Args and Returns
entries for original_maql, extra_message, and error_label, and describe the
returned placeholder MAQL string; keep the existing behavior unchanged and make
the docstring consistent with other public APIs used by cloud_metric.py.

Source: Coding guidelines

src/gooddata_legacy2cloud/metrics/cloud_metric.py (1)

92-97: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Exception logged without traceback.

logger.error("Metric '%s': %s", self.meta["title"], e) drops the stack trace, making it harder to diagnose why a legacy MAQL transformation failed in production. Use logger.exception(...) (or pass exc_info=True) inside the except block to retain the traceback.

♻️ Suggested fix
-            logger.error("Metric '%s': %s", self.meta["title"], e)
+            logger.exception("Metric '%s': %s", self.meta["title"], e)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/gooddata_legacy2cloud/metrics/cloud_metric.py` around lines 92 - 97, The
exception handling in the cloud metric transformation path logs the failure
without a traceback. Update the except block in the CloudMetric transformation
flow to use logger.exception or logger.error with exc_info=True so the stack
trace is preserved when legacy MAQL transformation fails. Keep the existing
context from self.meta["title"] and the caught exception, but ensure the logger
call in this error path records full exception details.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/gooddata_legacy2cloud/metrics/utils.py`:
- Around line 79-94: The MAQL error handling in metrics/utils.py assumes
json.loads(error_response.text) always returns an object, but valid JSON can
also be a string, number, or list, causing .get("detail", ...) to fail. Update
the error parsing in the build_placeholder_maql path to verify the parsed value
is a dict before reading detail, and otherwise fall back to the raw response
text. Add coverage around the error_response handling to include a non-object
JSON body so the behavior stays stable.

---

Nitpick comments:
In `@src/gooddata_legacy2cloud/metrics/cloud_metric.py`:
- Around line 92-97: The exception handling in the cloud metric transformation
path logs the failure without a traceback. Update the except block in the
CloudMetric transformation flow to use logger.exception or logger.error with
exc_info=True so the stack trace is preserved when legacy MAQL transformation
fails. Keep the existing context from self.meta["title"] and the caught
exception, but ensure the logger call in this error path records full exception
details.

In `@src/gooddata_legacy2cloud/metrics/utils.py`:
- Around line 44-59: The public helper build_placeholder_maql is missing the
required Google-style docstring sections. Update its docstring in utils.py to
include clear Args and Returns entries for original_maql, extra_message, and
error_label, and describe the returned placeholder MAQL string; keep the
existing behavior unchanged and make the docstring consistent with other public
APIs used by cloud_metric.py.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 973919f5-dcbb-4c75-8c9e-8ed580b7f5ab

📥 Commits

Reviewing files that changed from the base of the PR and between f2a299f and 163034d.

📒 Files selected for processing (7)
  • src/gooddata_legacy2cloud/metrics/cloud_metric.py
  • src/gooddata_legacy2cloud/metrics/utils.py
  • tests/data/metrics/legacy_objects/objects_by_uri.json
  • tests/data/metrics/test_cases/with_unresolved_identifier_cloud.json
  • tests/data/metrics/test_cases/with_unresolved_identifier_legacy.json
  • tests/test_metrics.py
  • tests/test_metrics_utils.py

Comment thread src/gooddata_legacy2cloud/metrics/utils.py
@janmatzek janmatzek force-pushed the jmat/SVS-1335-metrics-migration-omits-to-create-metrics-in-cloud-it-does-not-create-error-sqrt-1-placeholder-for-some-cases-with-computed-attributes branch from 163034d to fa75f62 Compare July 3, 2026 09:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/test_metrics_utils.py (1)

16-143: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add return type hints to test functions.

None of the test functions declare a return type annotation. As per coding guidelines, "Add comprehensive type hints to all new Python code, including parameter types, return types, and class attributes" applies to all new Python code, including tests.

♻️ Example fix pattern
-def test_comment_out_lines_prefixes_every_line():
+def test_comment_out_lines_prefixes_every_line() -> None:
     assert comment_out_lines("first line\nsecond line") == "`#first` line\n#second line"

Apply the same -> None annotation to all other test functions in this file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_metrics_utils.py` around lines 16 - 143, The test functions in
this module are missing return type annotations, so update each test such as
test_comment_out_lines_prefixes_every_line,
test_build_placeholder_maql_without_extra_message, and the other test_*
functions to explicitly declare a None return type. Keep the existing assertions
unchanged and apply the same -> None annotation consistently across all test
functions in the file.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_metrics_utils.py`:
- Line 1: The Python file header year is incorrect, so update the first-line
copyright notice to match the required GoodData standard. Replace the existing
`# (C) 2026 GoodData Corporation` header with the literal `# (C) 2025 GoodData
Corporation` at the top of `tests/test_metrics_utils.py`, keeping it as the
first line of the file.

---

Nitpick comments:
In `@tests/test_metrics_utils.py`:
- Around line 16-143: The test functions in this module are missing return type
annotations, so update each test such as
test_comment_out_lines_prefixes_every_line,
test_build_placeholder_maql_without_extra_message, and the other test_*
functions to explicitly declare a None return type. Keep the existing assertions
unchanged and apply the same -> None annotation consistently across all test
functions in the file.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7467e9a2-635b-4178-b6d5-af1affede70c

📥 Commits

Reviewing files that changed from the base of the PR and between 163034d and fa75f62.

📒 Files selected for processing (7)
  • src/gooddata_legacy2cloud/metrics/cloud_metric.py
  • src/gooddata_legacy2cloud/metrics/utils.py
  • tests/data/metrics/legacy_objects/objects_by_uri.json
  • tests/data/metrics/test_cases/with_unresolved_identifier_cloud.json
  • tests/data/metrics/test_cases/with_unresolved_identifier_legacy.json
  • tests/test_metrics.py
  • tests/test_metrics_utils.py
✅ Files skipped from review due to trivial changes (3)
  • tests/data/metrics/test_cases/with_unresolved_identifier_legacy.json
  • tests/data/metrics/legacy_objects/objects_by_uri.json
  • tests/test_metrics.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/data/metrics/test_cases/with_unresolved_identifier_cloud.json
  • src/gooddata_legacy2cloud/metrics/cloud_metric.py
  • src/gooddata_legacy2cloud/metrics/utils.py

Comment thread tests/test_metrics_utils.py
@janmatzek janmatzek merged commit 28e1ab7 into gooddata:master Jul 3, 2026
2 checks passed
@janmatzek janmatzek deleted the jmat/SVS-1335-metrics-migration-omits-to-create-metrics-in-cloud-it-does-not-create-error-sqrt-1-placeholder-for-some-cases-with-computed-attributes branch July 3, 2026 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants