Skip to content

fix(admin): include context in bucket error messages#4777

Open
drernie wants to merge 4 commits intomasterfrom
quilt3-missing-bucket
Open

fix(admin): include context in bucket error messages#4777
drernie wants to merge 4 commits intomasterfrom
quilt3-missing-bucket

Conversation

@drernie
Copy link
Member

@drernie drernie commented Mar 21, 2026

Summary

  • quilt3.admin.buckets.add/update/remove now include the bucket name in all error messages (e.g. BucketAlreadyAdded, BucketNotFound, IndexingInProgress)
  • SNS ARN is included in SnsInvalid and NotificationTopicNotFound errors
  • BucketNotFoundError (previously raised with None message) now surfaces the bucket name
  • tabulator.list_tables passes the bucket name to BucketNotFoundError

Test plan

  • Existing test_admin_api.py tests updated and passing (76/77 pass; 1 pre-existing unrelated pydantic failure in test_api_keys_list)
  • Manually verify error messages include bucket name by calling quilt3.admin.buckets.add with a nonexistent bucket

🤖 Generated with Claude Code

Greptile Summary

This PR improves error message quality across quilt3.admin.buckets by threading contextual information (bucket name and SNS ARN) through the internal result-handler helpers so failures are easier to diagnose. It also fixes a pre-existing bug in tabulator.list_tables where BucketNotFoundError was raised as a bare class reference rather than an instantiated exception.

Key changes:

  • _handle_bucket_add/update/remove_result helpers now accept name and sns_notification_arn and embed them in relevant error messages
  • BucketNotFoundError gains an optional name parameter and surfaces it in the message (gracefully omitting it when None)
  • tabulator.list_tables now correctly instantiates BucketNotFoundError(bucket_name) instead of raising the class itself
  • All related tests updated to assert the new message strings
  • CHANGELOG entry added (note: PR link references #4776 instead of #4777)

Confidence Score: 4/5

  • Safe to merge with minor polish; no correctness or data-loss concerns.
  • All logic changes are straightforward and well-tested. The only issues are a wrong PR number in the CHANGELOG, a type-annotation inaccuracy (str = None vs str | None = None), and a minor UX inconsistency where SNS error messages display the literal string None when no ARN was supplied — the same pattern that BucketNotFoundError already handles conditionally. None of these affect runtime correctness.
  • No files require special attention beyond the minor fixes noted.

Important Files Changed

Filename Overview
api/python/quilt3/admin/buckets.py Helper functions now receive name and sns_notification_arn context and include them in error messages. Logic is correct; minor UX issue when SNS ARN is None.
api/python/quilt3/admin/exceptions.py BucketNotFoundError now accepts an optional bucket name and conditionally includes it in the message. Type annotation name: str = None should be `str
api/python/quilt3/admin/tabulator.py Fixes a pre-existing bug where BucketNotFoundError was raised as a class reference instead of an instantiated exception; now correctly passes bucket_name.
api/python/tests/test_admin_api.py Test expectations updated to match new error message formats; SNS tests correctly assert None when no ARN is passed in the test setup.
docs/CHANGELOG.md New unreleased section added with accurate description; links to PR #4776 instead of the correct #4777.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant buckets.py
    participant GraphQL Client
    participant _handle_result

    Caller->>buckets.py: add(name, title, sns_notification_arn=...)
    buckets.py->>GraphQL Client: bucket_add(input)
    GraphQL Client-->>buckets.py: result (union type)
    buckets.py->>_handle_result: _handle_bucket_add_result(result, name, sns_notification_arn)
    alt BucketAddSuccess
        _handle_result-->>Caller: Bucket
    else BucketAlreadyAdded
        _handle_result-->>Caller: Quilt3AdminError("Bucket already added: {name!r}")
    else BucketDoesNotExist
        _handle_result-->>Caller: Quilt3AdminError("Bucket does not exist in S3: {name!r}")
    else SnsInvalid / NotificationTopicNotFound
        _handle_result-->>Caller: Quilt3AdminError("...SNS...: {sns_notification_arn!r}")
    end

    Caller->>buckets.py: update(name, title, ...)
    buckets.py->>GraphQL Client: bucket_update(name, input)
    GraphQL Client-->>buckets.py: result
    buckets.py->>_handle_result: _handle_bucket_update_result(result, name, sns_notification_arn)
    alt BucketNotFound
        _handle_result-->>Caller: BucketNotFoundError(name)
    end

    Caller->>buckets.py: remove(name)
    buckets.py->>GraphQL Client: bucket_remove(name)
    GraphQL Client-->>buckets.py: result
    buckets.py->>_handle_result: _handle_bucket_remove_result(result, name)
    alt BucketNotFound
        _handle_result-->>Caller: BucketNotFoundError(name)
    else IndexingInProgress
        _handle_result-->>Caller: Quilt3AdminError("...indexing...: {name!r}")
    end
Loading

Last reviewed commit: "docs(changelog): not..."

Greptile also left 3 inline comments on this PR.

drernie and others added 3 commits March 21, 2026 14:49
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add bucket name and SNS ARN to error messages across add/update/remove
so callers can identify which resource caused the failure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review.
@claude review


## unreleased

### Python API
Copy link
Contributor

Choose a reason for hiding this comment

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

P2 Wrong PR number in CHANGELOG

The CHANGELOG entry links to #4776, but this change is being introduced in PR #4777. This will result in a broken or misleading reference in the project history.

Suggested change
### Python API
* [Fixed] `quilt3.admin.buckets.add/update/remove` now include the bucket name (and SNS ARN where applicable) in error messages, making failures easier to debug ([#4777](https://github.com/quiltdata/quilt/pull/4777))

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed, pushed.

raise exceptions.Quilt3AdminError(result.message)
if isinstance(result, _graphql_client.BucketAddBucketAddSnsInvalid):
raise exceptions.Quilt3AdminError("Invalid SNS notification ARN")
raise exceptions.Quilt3AdminError(f"Invalid SNS notification ARN: {sns_notification_arn!r}")
Copy link
Contributor

Choose a reason for hiding this comment

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

P2 SNS error message shows literal None when no ARN was provided

When sns_notification_arn is None (not passed by the caller), the error messages become "Invalid SNS notification ARN: None" and "Notification topic not found: None". The string None suggests the user explicitly passed None as the ARN value, which is misleading. This is the same pattern that BucketNotFoundError avoids by using a conditional.

Consider following the same pattern for consistency:

    if isinstance(result, _graphql_client.BucketAddBucketAddSnsInvalid):
        arn_info = f": {sns_notification_arn!r}" if sns_notification_arn else ""
        raise exceptions.Quilt3AdminError(f"Invalid SNS notification ARN{arn_info}")

This also applies to the NotificationTopicNotFound case on line 104, and to the equivalent branches in _handle_bucket_update_result (lines 182 and 186).

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed — SNS/ARN suffix now omitted when ARN is None, using the same conditional pattern as BucketNotFoundError.

class BucketNotFoundError(Quilt3AdminError):
def __init__(self):
super().__init__(None)
def __init__(self, name: str = None):
Copy link
Contributor

Choose a reason for hiding this comment

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

P2 Incorrect type annotation for name parameter

name: str = None is technically incorrect — a parameter with a default of None should be annotated as Optional[str] (or str | None in Python 3.10+) to accurately reflect that None is a valid value. Mypy and similar type checkers will flag this as an error. Since the file doesn't currently import typing, the simplest fix is to use the union syntax:

Suggested change
def __init__(self, name: str = None):
def __init__(self, name: str | None = None):

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed — updated to str | None = None.

@codecov
Copy link

codecov bot commented Mar 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 28.55%. Comparing base (ce52cf2) to head (078bf82).

❗ There is a different number of reports uploaded between BASE (ce52cf2) and HEAD (078bf82). Click for more details.

HEAD has 40 uploads less than BASE
Flag BASE (ce52cf2) HEAD (078bf82)
py-shared 2 1
lambda 28 14
api-python 24 0
catalog 2 1
Additional details and impacted files
@@             Coverage Diff             @@
##           master    #4777       +/-   ##
===========================================
- Coverage   44.33%   28.55%   -15.78%     
===========================================
  Files         813      724       -89     
  Lines       32734    24677     -8057     
  Branches     5723     5723               
===========================================
- Hits        14511     7046     -7465     
+ Misses      16220    15628      -592     
  Partials     2003     2003               
Flag Coverage Δ
api-python ?
catalog 19.53% <ø> (ø)
lambda 96.63% <ø> (ø)
py-shared 98.18% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Use str | None annotation on BucketNotFoundError
- Omit SNS ARN suffix when ARN is None (avoids misleading 'None' in message)
- Fix CHANGELOG PR link (#4776#4777)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant