Skip to content

feat: Display ErrorBuilder enrichments in early startup errors#1892

Merged
aknysh merged 2 commits intomainfrom
osterman/error-builder-profile
Dec 19, 2025
Merged

feat: Display ErrorBuilder enrichments in early startup errors#1892
aknysh merged 2 commits intomainfrom
osterman/error-builder-profile

Conversation

@osterman
Copy link
Copy Markdown
Member

@osterman osterman commented Dec 18, 2025

what

  • Added structured plain text error formatting to display ErrorBuilder enrichments (hints, explanations, context) even when the markdown renderer is not initialized
  • Fixes profile not found errors during config loading to show which profile is missing and how to configure it

why

  • Early startup errors (before config is loaded) were falling back to bare plain text output that only showed the sentinel error message
  • Rich error information from ErrorBuilder (hints, explanations, context) was being lost because the markdown renderer wasn't initialized yet
  • This made errors like "Error: profile not found" unhelpful as they didn't tell users which profile was missing or how to fix it

references

  • Improves user experience for all early startup errors that use the ErrorBuilder pattern
  • Particularly beneficial for profile configuration errors showing profile name, search paths, and actionable hints

Summary by CodeRabbit

  • Bug Fixes
    • Improved error output when rich rendering is unavailable: displays structured sections for explanations, hints, and contextual key/value details while preserving legacy plain output and a helpful default title.
  • Tests
    • Added tests validating enriched error formatting, plain-error fallback, and default title behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

…r enrichments

Add structured plain text error formatting to display ErrorBuilder
enrichments (hints, explanations, context) even when markdown renderer
is not initialized. This fixes profile not found errors during config
loading to show which profile is missing and how to configure it.

Before: 'Error: profile not found'
After: Displays profile name, search paths, hints, and context
@osterman osterman requested a review from a team as a code owner December 18, 2025 19:38
@github-actions github-actions bot added the size/m Medium size PR label Dec 18, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 18, 2025

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 18, 2025

📝 Walkthrough

Walkthrough

Adds structured plain error printing functions to render error explanations, hints, and context when the Markdown renderer is unavailable or fails. Updates fallback logic and adds tests covering enriched and simple error outputs.

Changes

Cohort / File(s) Summary
Error printing implementation
errors/error_funcs.go
Adds structured plain error printing functions (printStructuredPlainError, printErrorDetails, printErrorHints, printErrorContext, extractContextPairs) and imports github.com/cockroachdb/errors. Updates fallback in printMarkdownError to use the structured plain path and preserves legacy plain output path.
Error printing tests
errors/error_funcs_test.go
Adds TestPrintStructuredPlainError with three subtests: enriched errors (explanations/hints/context), simple errors (no enrichments), and default title behavior. Captures/stubs stderr via an OS pipe to assert printed output.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review attention: errors/error_funcs.go (correct extraction/formatting of enrichments, nil/error handling, dependency usage of cockroachdb/errors)
  • Tests: errors/error_funcs_test.go (stderr capture/restore, assertions for different enrichment cases)

Suggested labels

minor

Pre-merge checks and finishing touches

✅ Passed checks (3 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: adding structured error formatting to display ErrorBuilder enrichments in early startup errors when the markdown renderer is unavailable.
Docstring Coverage ✅ Passed Docstring coverage is 81.82% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch osterman/error-builder-profile

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 139c0db and 15136d2.

📒 Files selected for processing (1)
  • errors/error_funcs.go (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: NEVER use fmt.Fprintf(os.Stdout/Stderr) or fmt.Println(); use data.* or ui.* functions instead
All comments must end with periods (enforced by godot linter)
Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions for performance tracking; use nil if no atmosConfig param
All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use errors.Is() for error checking; NEVER use dynamic errors directly
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation; never create manual mocks
Keep files small...

Files:

  • errors/error_funcs.go
🧠 Learnings (18)
📓 Common learnings
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: Commands should use `PrintErrorMarkdownAndExit` with empty title and suggestion (`"", err, ""`) for general error handling. Specific titles like "Invalid Usage" or "File Not Found" should only be used for validation or specific error scenarios.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2024-10-12T18:38:28.458Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 715
File: pkg/logger/logger.go:21-32
Timestamp: 2024-10-12T18:38:28.458Z
Learning: In Go code, avoid prefixing struct names with 'I' (e.g., `IError`) as it can be confusing, suggesting an interface. Use descriptive names for structs to improve code clarity.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to cmd/**/*.go : Embed CLI examples from cmd/markdown/*_usage.md using //go:embed; render with utils.PrintfMarkdown()

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2024-11-30T22:07:08.610Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 810
File: internal/exec/yaml_func_terraform_output.go:35-40
Timestamp: 2024-11-30T22:07:08.610Z
Learning: In the Go function `processTagTerraformOutput` in `internal/exec/yaml_func_terraform_output.go`, parameters cannot contain spaces. The code splits the input by spaces, and if the parameters contain spaces, `len(parts) != 3` will fail and show an error to the user.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2024-12-02T21:26:32.337Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-01-07T20:38:09.618Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 896
File: cmd/editor_config.go:37-40
Timestamp: 2025-01-07T20:38:09.618Z
Learning: Error handling suggestion for `cmd.Help()` in `cmd/editor_config.go` was deferred as the code is planned for future modifications.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-09-30T19:03:50.738Z
Learnt from: Cerebrovinny
Repo: cloudposse/atmos PR: 1560
File: pkg/utils/string_utils.go:43-64
Timestamp: 2025-09-30T19:03:50.738Z
Learning: In the Atmos codebase, YAML tags like !terraform.output rely on positional arguments, so the SplitStringByDelimiter function in pkg/utils/string_utils.go must preserve empty strings (even after trimming quotes) to maintain the correct number of positional arguments. Filtering out empty values after trimming would collapse the array and break these function calls.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2024-10-23T21:36:40.262Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 740
File: cmd/cmd_utils.go:340-359
Timestamp: 2024-10-23T21:36:40.262Z
Learning: In the Go codebase for Atmos, when reviewing functions like `checkAtmosConfig` in `cmd/cmd_utils.go`, avoid suggesting refactoring to return errors instead of calling `os.Exit` if such changes would significantly increase the scope due to the need to update multiple call sites.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2024-12-17T07:08:41.288Z
Learnt from: aknysh
Repo: cloudposse/atmos PR: 863
File: internal/exec/yaml_func_terraform_output.go:34-38
Timestamp: 2024-12-17T07:08:41.288Z
Learning: In the `processTagTerraformOutput` function within `internal/exec/yaml_func_terraform_output.go`, parameters are separated by spaces and do not contain spaces. Therefore, using `strings.Fields()` for parsing is acceptable, and there's no need to handle parameters with spaces.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-12-13T06:10:13.688Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:13.688Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to **/*.go : All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use errors.Is() for error checking; NEVER use dynamic errors directly

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: The `describe config` command should use `PrintErrorMarkdownAndExit` with empty title and suggestion for consistency with other commands.

Applied to files:

  • errors/error_funcs.go
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Summary
🔇 Additional comments (5)
errors/error_funcs.go (5)

3-17: Imports look good.

The import groups are properly organized with stdlib first, third-party second, and atmos packages last. The new cockroachdb/errors import is correctly placed.


93-118: Solid implementation.

The structured error output is well-organized. Modular approach with dedicated helpers for details, hints, and context keeps it maintainable. The default title handling and title casing are consistent with printMarkdownError.


120-163: Helper functions are clean and consistent.

Good use of early returns for empty cases. The SplitN(pair, "=", 2) in printErrorContext correctly handles values that may contain = characters. Bullet formatting is uniform.


286-304: Fallback logic updated correctly.

Both paths (nil renderer and render failure) now invoke printStructuredPlainError, ensuring ErrorBuilder enrichments surface even for early startup errors. Comments clearly explain the rationale.


79-91: Comment clarification is helpful.

The updated comment accurately describes the fallback scenario.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 54f9778 and 139c0db.

📒 Files selected for processing (2)
  • errors/error_funcs.go (5 hunks)
  • errors/error_funcs_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*.go: Use Viper for managing configuration, environment variables, and flags in CLI commands
Use interfaces for external dependencies to facilitate mocking and consider using testify/mock for creating mock implementations
All code must pass golangci-lint checks
Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using fmt.Errorf("context: %w", err), and consider using custom error types for domain-specific errors
Follow standard Go coding style: use gofmt and goimports to format code, prefer short descriptive variable names, use kebab-case for command-line flags, and snake_case for environment variables
Document all exported functions, types, and methods following Go's documentation conventions
Document complex logic with inline comments in Go code
Support configuration via files, environment variables, and flags following the precedence order: flags > environment variables > config file > defaults
Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

**/*.go: NEVER use fmt.Fprintf(os.Stdout/Stderr) or fmt.Println(); use data.* or ui.* functions instead
All comments must end with periods (enforced by godot linter)
Organize imports in three groups separated by blank lines, sorted alphabetically: 1) Go stdlib, 2) 3rd-party (NOT cloudposse/atmos), 3) Atmos packages; maintain aliases: cfg, log, u, errUtils
Add defer perf.Track(atmosConfig, "pkg.FuncName")() + blank line to all public functions for performance tracking; use nil if no atmosConfig param
All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use errors.Is() for error checking; NEVER use dynamic errors directly
Use go.uber.org/mock/mockgen with //go:generate directives for mock generation; never create manual mocks
Keep files small...

Files:

  • errors/error_funcs_test.go
  • errors/error_funcs.go
**/*_test.go

📄 CodeRabbit inference engine (.cursor/rules/atmos-rules.mdc)

**/*_test.go: Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages
Use table-driven tests for testing multiple scenarios in Go
Include integration tests for command flows and test CLI end-to-end when possible with test fixtures

**/*_test.go: Prefer unit tests with mocks over integration tests; use interfaces + dependency injection for testability; generate mocks with go.uber.org/mock/mockgen; use table-driven tests; target >80% coverage
Test behavior, not implementation; never test stub functions; avoid tautological tests; make code testable via DI; no coverage theater; remove always-skipped tests; use errors.Is() for error checking

Files:

  • errors/error_funcs_test.go
🧠 Learnings (12)
📓 Common learnings
Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:37.766Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: Commands should use `PrintErrorMarkdownAndExit` with empty title and suggestion (`"", err, ""`) for general error handling. Specific titles like "Invalid Usage" or "File Not Found" should only be used for validation or specific error scenarios.
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to **/*_test.go : Test behavior, not implementation; never test stub functions; avoid tautological tests; make code testable via DI; no coverage theater; remove always-skipped tests; use errors.Is() for error checking

Applied to files:

  • errors/error_funcs_test.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning the error instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions.

Applied to files:

  • errors/error_funcs_test.go
  • errors/error_funcs.go
📚 Learning: 2025-06-02T14:12:02.710Z
Learnt from: milldr
Repo: cloudposse/atmos PR: 1229
File: internal/exec/workflow_test.go:0-0
Timestamp: 2025-06-02T14:12:02.710Z
Learning: In the atmos codebase, workflow error handling was refactored to use `PrintErrorMarkdown` followed by returning specific error variables (like `ErrWorkflowNoSteps`, `ErrInvalidFromStep`, `ErrInvalidWorkflowStepType`, `ErrWorkflowStepFailed`) instead of `PrintErrorMarkdownAndExit`. This pattern allows proper error testing without the function terminating the process with `os.Exit`, enabling unit tests to assert on error conditions while maintaining excellent user-facing error formatting.

Applied to files:

  • errors/error_funcs_test.go
  • errors/error_funcs.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: Commands should use `PrintErrorMarkdownAndExit` with empty title and suggestion (`"", err, ""`) for general error handling. Specific titles like "Invalid Usage" or "File Not Found" should only be used for validation or specific error scenarios.

Applied to files:

  • errors/error_funcs_test.go
  • errors/error_funcs.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*_test.go : Every new feature must include comprehensive unit tests targeting >80% code coverage for all packages

Applied to files:

  • errors/error_funcs_test.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Follow Go's error handling idioms: use meaningful error messages, wrap errors with context using `fmt.Errorf("context: %w", err)`, and consider using custom error types for domain-specific errors

Applied to files:

  • errors/error_funcs_test.go
  • errors/error_funcs.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Provide clear error messages to users, include troubleshooting hints when appropriate, and log detailed errors for debugging

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2024-10-12T18:38:28.458Z
Learnt from: osterman
Repo: cloudposse/atmos PR: 715
File: pkg/logger/logger.go:21-32
Timestamp: 2024-10-12T18:38:28.458Z
Learning: In Go code, avoid prefixing struct names with 'I' (e.g., `IError`) as it can be confusing, suggesting an interface. Use descriptive names for structs to improve code clarity.

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-12-16T18:20:55.630Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-16T18:20:55.630Z
Learning: Applies to **/*.go : All errors MUST be wrapped using static errors defined in errors/errors.go; use errors.Join for combining multiple errors; use fmt.Errorf with %w for adding string context; use error builder for complex errors; use errors.Is() for error checking; NEVER use dynamic errors directly

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-11-24T17:35:37.209Z
Learnt from: CR
Repo: cloudposse/atmos PR: 0
File: .cursor/rules/atmos-rules.mdc:0-0
Timestamp: 2025-11-24T17:35:37.209Z
Learning: Applies to **/*.go : Use Viper for managing configuration, environment variables, and flags in CLI commands

Applied to files:

  • errors/error_funcs.go
📚 Learning: 2025-02-03T06:00:11.419Z
Learnt from: samtholiya
Repo: cloudposse/atmos PR: 959
File: cmd/describe_config.go:20-20
Timestamp: 2025-02-03T06:00:11.419Z
Learning: The `describe config` command should use `PrintErrorMarkdownAndExit` with empty title and suggestion for consistency with other commands.

Applied to files:

  • errors/error_funcs.go
🧬 Code graph analysis (1)
errors/error_funcs_test.go (3)
errors/builder.go (1)
  • Build (24-37)
errors/errors.go (1)
  • ErrProfileNotFound (208-208)
errors/exit_code.go (1)
  • WithExitCode (40-48)
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Acceptance Tests (macos)
  • GitHub Check: Acceptance Tests (windows)
  • GitHub Check: Acceptance Tests (linux)
  • GitHub Check: Summary
🔇 Additional comments (5)
errors/error_funcs.go (4)

9-9: LGTM - Import addition necessary for enrichments extraction.

The github.com/cockroachdb/errors import is required for GetAllDetails, GetAllHints, and GetAllSafeDetails used in the new structured plain error helpers.


93-118: LGTM - Structured plain error formatting looks solid.

The function correctly defaults the title to "Error", delegates to helper functions for each enrichment type, and preserves backward compatibility with the legacy suggestion parameter. The structured output will provide much better visibility for early startup errors.


120-148: LGTM - Error details and hints extraction is well-structured.

Both printErrorDetails and printErrorHints correctly check for empty results before printing section headers. The filtering of internal prefixes (TITLE:, EXAMPLE:) in hints is appropriate.


283-289: LGTM - Fallback behavior correctly updated.

The updated calls to printStructuredPlainError ensure ErrorBuilder enrichments are displayed even when the markdown renderer is unavailable. This addresses the PR objective of surfacing rich error information during early startup.

Also applies to: 297-299

errors/error_funcs_test.go (1)

305-413: LGTM - Comprehensive test coverage for structured plain error output.

The test suite validates all critical paths:

  • ErrorBuilder enrichments (explanations, hints, context) are correctly extracted and displayed
  • Simple errors without enrichments fall back gracefully with title and suggestion
  • Default title behavior works when title is empty
  • Proper stderr capture/restore pattern throughout

The assertions check both positive cases (enrichment sections present) and negative cases (sections absent for simple errors), which is exactly right.

@codecov
Copy link
Copy Markdown

codecov bot commented Dec 18, 2025

Codecov Report

❌ Patch coverage is 94.23077% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.20%. Comparing base (54f9778) to head (15136d2).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
errors/error_funcs.go 94.23% 2 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1892      +/-   ##
==========================================
+ Coverage   73.19%   73.20%   +0.01%     
==========================================
  Files         609      609              
  Lines       56883    56933      +50     
==========================================
+ Hits        41634    41680      +46     
- Misses      12312    12315       +3     
- Partials     2937     2938       +1     
Flag Coverage Δ
unittests 73.20% <94.23%> (+0.01%) ⬆️

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

Files with missing lines Coverage Δ
errors/error_funcs.go 70.46% <94.23%> (+4.81%) ⬆️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Address CodeRabbit feedback about fragile space-based parsing in
extractContextPairs. The SafeDetails format is established by
ErrorBuilder.WithContext() which uses space-separated key=value pairs.
This is a known limitation - values containing spaces won't parse correctly.

Changes:
- Document the space limitation in function comments
- Add TrimSpace for cleaner parsing
- Add empty string check for robustness
@aknysh aknysh added the patch A minor, backward compatible change label Dec 19, 2025
@aknysh aknysh merged commit a54c769 into main Dec 19, 2025
63 of 64 checks passed
@aknysh aknysh deleted the osterman/error-builder-profile branch December 19, 2025 01:19
@github-actions
Copy link
Copy Markdown

These changes were released in v1.203.0-test.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch A minor, backward compatible change size/m Medium size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants