Skip to content

fix: sanitize git GraphQL query import errors#9815

Closed
Timtech4u wants to merge 4 commits into
opsmill:stablefrom
Timtech4u:fix/sanitize-git-query-import-errors
Closed

fix: sanitize git GraphQL query import errors#9815
Timtech4u wants to merge 4 commits into
opsmill:stablefrom
Timtech4u:fix/sanitize-git-query-import-errors

Conversation

@Timtech4u

@Timtech4u Timtech4u commented Jul 5, 2026

Copy link
Copy Markdown

Problem

Git repository imports can fail while creating CoreGraphQLQuery nodes. When that happens, the SDK GraphQLError currently surfaces the full generated mutation, variables, location reprs, and traceback-heavy text in task logs. That makes a user/configuration error hard to scan and can expose implementation details that are not useful to operators.

Change

  • catch infrahub_sdk.exceptions.GraphQLError around GraphQL query creation during Git import
  • convert SDK validation output into a concise RepositoryConfigurationError that keeps the repository name, query name, and server validation message
  • strip raw GraphQL mutation text, variables, and SourceLocation reprs from the operator-facing error/log message
  • add regression coverage proving the sanitized error keeps the useful context without leaking the raw payload

Before / After

Before, the worker/task output could include the full CoreGraphQLQueryCreate mutation and SDK exception payload.

After, the task reports a focused message like:

Unable to import GraphQL query 'backbone_service' from repository 'opsmill-demo-edge-clean-message': Query is not valid: Cannot query field 'InfraBackBoneService' on type 'Query'.

Screenshot

Filtered task log showing the sanitized RepositoryConfigurationError after reproducing the Git import failure locally:

InfraHub task log showing sanitized RepositoryConfigurationError

Scope

This targets the Git integration path from #7498. It is related to the broader user-error logging cleanup in #4589, but intentionally does not attempt to change general API/GraphQL resolver logging in this PR.

Testing

  • uv run ruff check backend/infrahub/git/integrator.py backend/tests/component/git/test_graphql_query_import.py
  • uv run pytest backend/tests/component/git/test_graphql_query_import.py -q
  • local Docker verification against the InfraHub task UI with a failing Git GraphQL import

Addresses #7498. Related to #4589.

@Timtech4u
Timtech4u requested a review from a team as a code owner July 5, 2026 10:55
@Timtech4u

Copy link
Copy Markdown
Author

Hi @fatih-acar and @saltas888, I opened this small PR after reproducing the noisy Git GraphQL query import error locally and matching it to #7498.

The change is intentionally narrow: it catches the SDK GraphQLError in the Git integration query-creation path, keeps the repository/query context, and strips the raw generated mutation/variables from the operator-facing task message. I also added regression coverage and verified the behavior in a local InfraHub task UI run.

Would appreciate your review when you have a chance.

@ogenstad ogenstad left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In Infrahub 1.10.0 we introduced an error catalogue: https://github.com/opsmill/infrahub/blob/infrahub-v1.10.2/schema/error-catalogue.json

These errors will be added in the error extension field of the GraphQL errors, the idea is that the catalogue will grow over time and that we'll use this json file to generate error bindings that the SDK then uses so that we get the enriched errors directly within the SDK. (some more information about this can be found here: https://github.com/opsmill/infrahub/tree/infrahub-v1.10.2/dev/specs/infp-468-graphql-error-catalogue)

As such I think the next step for this should be to introduce this parsing within the SDK and ensure that the backend raises the correct enriched error instead of having a method within the integrator that tries to parse the error again with something like the _clean_sdk_graphql_error_message() function.

import shutil
from pathlib import Path
from unittest.mock import AsyncMock, patch
from unittest.mock import AsyncMock, MagicMock, patch

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We don't want to use MagicMock for anything new, the goal is to remove any MagicMock or AsyncMock.

@Timtech4u

Timtech4u commented Jul 5, 2026

Copy link
Copy Markdown
Author

Thanks @ogenstad, agreed. I ran this locally and the better fix is to move it down a layer instead of parsing in the integrator.

I’ll update the PR to add a GRAPHQL_QUERY_INVALID catalogue error from CoreGraphQLQueryCreate, make the SDK surface the server error message without including query/variables, and keep the Git integrator just wrapping that concise SDK error.

I’ll keep broader validation/catalogue cases out of this PR unless you’d prefer those included too.

… queries [opsmill#7498]

Rework the git import error handling per review feedback:

- Add a GRAPHQL_QUERY_INVALID catalogue entry (422, evolving), raised as
  GraphQLQueryInvalidError from the GraphQLQuery create/update/upsert
  mutations with the concise graphql-core validation messages, replacing
  ValueError("Query is not valid, [GraphQLError(...)]").
- Regenerate schema/error-catalogue.json, the frontend error bindings and
  the error-catalogue reference docs.
- Remove the regex-based message re-parsing from the git integrator: both
  the create and update import paths now wrap the server-provided error
  messages in RepositoryConfigurationError and suppress the chained SDK
  exception, which embeds the full rendered mutation.
- Replace the MagicMock/AsyncMock regression test with a pytest-httpx test
  driving the real SDK client, and add mutation-level tests asserting the
  catalogued error extensions for create and update.

A follow-up in opsmill/infrahub-sdk-python will parse the error catalogue
extensions so SDK consumers get the enriched error without message joining.
@Timtech4u

Copy link
Copy Markdown
Author

As such I think the next step for this should be to introduce this parsing within the SDK and ensure that the backend raises the correct enriched error

Done in 48ba4c2. The backend now raises a catalogued GRAPHQL_QUERY_INVALID error (422) from the GraphQLQuery mutations, and the integrator simply wraps the concise server messages with no parsing. The tests were rebuilt without MagicMock, driving the real SDK client over pytest-httpx.

The SDK parsing is up in opsmill/infrahub-sdk-python#1140. GraphQLError now exposes the catalogue extensions via details and codes, and its message no longer embeds the query or variables. Once that lands, the integrator can drop its message joining too.

Timtech4u and others added 2 commits July 6, 2026 14:53
The leak checks on caplog were only meaningful if log capture worked at
all; a positive assertion on the sanitized message now guards them
against passing vacuously.
@dgarros dgarros closed this Jul 21, 2026
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.

4 participants