feat(error): detect accessNotConfigured and guide users to enable APIs#33
Conversation
When the Google API returns a 403 with reason accessNotConfigured, gws now: - Extracts the GCP Console enable URL from the error message. - Adds an optional enable_url field to the JSON error output. - Prints an actionable hint with the enable URL to stderr. Also adds extract_enable_url() helper with tests, and a Troubleshooting section to README. Fixes googleworkspace#31
🦋 Changeset detectedLatest commit: 756de45 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the user experience of the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a great user experience improvement for handling accessNotConfigured errors from Google APIs. By detecting this specific error, parsing the console URL from the message, and providing a helpful hint on stderr, it makes it much easier for users to resolve disabled API issues. The changes are well-structured, including updates to the error handling logic, new tests, and clear documentation in the README.
I have one suggestion to improve the robustness of the URL extraction logic to handle cases where punctuation might follow the URL in the error message.
|
/gemini review |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
jpoehnelt
left a comment
There was a problem hiding this comment.
Good UX improvement — surfacing a direct GCP console link for accessNotConfigured is exactly the kind of actionable guidance that saves users from digging through error messages.
A few notes:
-
extract_enable_urlfragility — the parser splits on the literal string"visiting "and then takes the first whitespace-delimited token. This works for the current Google error message format, but the format is not part of any stable API contract. Consider adding a comment noting this is a best-effort parse, and thatenable_url: Noneis the graceful fallback if the format changes. A test for a message that lacks the pattern (already present:test_extract_enable_url_no_url) and one for a future format variation would strengthen confidence. -
stderr vs stdout — printing guidance to
stderrwhile the JSON error goes tostdoutis the right separation. Worth documenting in the README or help text that--format jsonoutput should be captured from stdout only. -
enable_urlin JSON output — addingenable_urlas an optional field to theerrorJSON object is a small but technically additive schema change. Machine consumers that iterateerrorkeys could be surprised. Consider whether a"hint"wrapper object would be cleaner ("hint": {"enable_url": "..."}). -
Reason fallback — the new
.or_else(|| err_obj.get("reason")...)fallback for top-level reason field is a good defensive addition. Test coverage for a response with only a top-levelreason(noerrorsarray) would complete the picture. -
Test assertion for absent
enable_url—assert!(json["error"]["enable_url"].is_null())is correct for serde_json, but only if the key is truly absent (serde_json returnsValue::Nullfor missing keys). This is fine here; just noting it for clarity.
|
Addressed Gemini review feedback:\n\n- Hardened |
jpoehnelt
left a comment
There was a problem hiding this comment.
Thanks for addressing the feedback!
Replacing the regex with basic string splitting and matching punctuation is much more deterministic and less prone to panicking. The additional test coverage for punctuation trimming (test_extract_enable_url_trims_trailing_punctuation) gives confidence that it correctly strips trailing dots and commas from the parsed URL.
The changes look solid to me. LGTM!
googleworkspace#33) * feat(error): detect accessNotConfigured and guide users to enable APIs When the Google API returns a 403 with reason accessNotConfigured, gws now: - Extracts the GCP Console enable URL from the error message. - Adds an optional enable_url field to the JSON error output. - Prints an actionable hint with the enable URL to stderr. Also adds extract_enable_url() helper with tests, and a Troubleshooting section to README. Fixes googleworkspace#31 * fix(error): trim trailing punctuation from accessNotConfigured enable URL
Summary
Implements #31.
When the Google API returns a 403 with reason
accessNotConfigured(i.e., the required API is disabled for the GCP project),gwsnow surfaces a user-friendly error instead of a raw JSON blob.Changes
src/error.rsenable_url: Option<String>field toGwsError::Apivariant.to_json()includesenable_urlin JSON output when present (backward-compatible — new optional field only).print_error_json()now prints actionable guidance to stderr foraccessNotConfigurederrors, including the direct GCP Console link.src/executor.rsextract_enable_url(message: &str) -> Option<String>— parses the GCP enable URL from the error message (no external deps; pure string splitting).handle_error_response()now detectsaccessNotConfiguredreason (botherrors[0].reasonand top-levelreasonfields) and populatesenable_url.enable_url: NoneinGwsError::Apiconstructors.Tests added
test_extract_enable_url_typical_message— parses URL from a realistic message.test_extract_enable_url_no_url— returnsNonefor messages without a URL.test_extract_enable_url_non_http— ignores non-HTTP URLs.test_handle_error_response_access_not_configured_with_url— end-to-end parse with top-levelreasonfield.test_handle_error_response_access_not_configured_errors_array— end-to-end parse witherrors[]array.accessNotConfiguredwith and withoutenable_url.README.mdaccessNotConfiguredexample, the JSON shape change, and step-by-step fix instructions..changeset/access-not-configured-guidance.md@googleworkspace/cli(patch bump).Example output
stdout (machine-readable, unchanged shape + optional field):
{ "error": { "code": 403, "message": "Gmail API has not been used in project 549352339482 ...", "reason": "accessNotConfigured", "enable_url": "https://console.developers.google.com/apis/api/gmail.googleapis.com/overview?project=549352339482" } }stderr (human-readable hint):
Quality checks
cargo fmt --all✅cargo test✅ — 306 passed, 0 failedcargo clippy --all-targets --all-features -- -D warnings— 7 pre-existing failures on upstreammain(not introduced by this PR). These failures exist in the same form on the upstream main branch:bool_assert_comparisonin main.rs tests,field_reassign_with_defaultin executor.rs tests, andmanual_containsin helpers. No new clippy errors introduced.Closes #31