Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DO NOT MERGE (needs review and testing). Break error into parts #715

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

haitham911
Copy link
Collaborator

@haitham911 haitham911 commented Oct 12, 2024

what

This pull request introduces error handling . Key changes include adding IError interface, updating error handling to use the new IError type, and setting the log level for detailed debug information.

why

Basically break error to parts. the parts that are info to info, and those that are debug to debug

issue url

https://linear.app/cloudposse/issue/DEV-340/change-log-level-of-output-when-imports-are-not-found-to-hide-this

Summary by CodeRabbit

  • New Features

    • Enhanced logging capabilities for command execution based on CLI configuration.
    • Improved error reporting with structured messages and debug information.
  • Bug Fixes

    • Updated error handling to provide clearer insights into issues encountered during stack configuration retrieval.

Copy link
Contributor

coderabbitai bot commented Oct 12, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes introduce enhancements to the logging and error handling mechanisms within the application. A new import for the logger package is added in cmd/root.go, facilitating improved command execution logging. Modifications in pkg/config/utils.go update error handling to utilize a new error structure that includes debug information. Additionally, pkg/logger/logger.go introduces new variables and methods to manage debug logging, including a new IError struct that formats error messages based on the log level. A new constant for CLI configuration is also defined.

Changes

File Change Summary
cmd/root.go Added import for logger package; updated Execute function to set log level for IError.
pkg/config/utils.go Established dependency on logger; modified error handling in FindAllStackConfigsInPathsForStack and FindAllStackConfigsInPaths to use &logger.IError.
pkg/logger/logger.go Added global variable PrintDebugPart; created SetPrintDebugPart(val string) function; defined IError struct with Error() method for enhanced error reporting.
pkg/config/const.go Added constant CliConfigPrefix for CLI configurations.
pkg/utils/log_utils.go Introduced mutex for thread-safe access to PrintDebugPart; updated SetPrintDebugPart to return an error; defined ExtendedError type with modified Error method.

Poem

In the code where rabbits hop,
New logs and errors make us stop.
With debug info shining bright,
Our paths are clearer, day and night.
Hooray for changes, let’s rejoice,
In every line, we hear the voice! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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: 6

🧹 Outside diff range comments (2)
pkg/logger/logger.go (1)

Line range hint 1-33: Overall, good implementation of debug logging enhancements

The changes effectively introduce new debug logging capabilities while maintaining backwards compatibility with existing logging methods. The new IError struct (to be renamed) allows for more detailed error messages when debugging is enabled, aligning well with the PR objectives.

To fully leverage these enhancements:

  1. Consider updating other parts of the codebase to use the new error structure where appropriate.
  2. Add documentation for the new functionality to guide other developers on its usage.

Great job on implementing these improvements in a non-intrusive manner!

pkg/config/utils.go (1)

Line range hint 1-130: Summary: Improved error handling and logging

The changes in this file successfully enhance the error handling and logging capabilities, aligning well with the PR objectives. The introduction of the IError struct allows for more detailed error reporting, including debug information, which will greatly aid in troubleshooting issues.

Key improvements:

  1. Addition of the logger package import.
  2. Consistent use of IError struct in error handling across functions.
  3. Inclusion of CLI configuration in error debug information.

These changes will contribute to better error management and easier debugging in the codebase.

To further improve the code:

  1. Consider creating helper functions for generating IError structures to reduce duplication.
  2. Explore the possibility of using constants or configuration values for debug info prefixes to ensure consistency.
  3. Review other parts of the codebase to apply similar error handling improvements for consistency across the project.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 7c41087 and 83674d1.

📒 Files selected for processing (3)
  • cmd/root.go (2 hunks)
  • pkg/config/utils.go (3 hunks)
  • pkg/logger/logger.go (1 hunks)
🧰 Additional context used
🔇 Additional comments (3)
cmd/root.go (2)

16-16: LGTM: New import for logger package.

The new import for the logger package is correctly placed and necessary for the new logging functionality.


16-16: Overall changes align well with PR objectives.

The introduced changes effectively enhance the error handling and logging capabilities of the application, which aligns perfectly with the stated PR objectives. The new import and the addition of log level setting based on CLI configuration are well-integrated into the existing code structure.

These modifications will allow for more structured error management and improved clarity in distinguishing between informational and debugging errors, as intended in the PR summary.

Also applies to: 75-76

pkg/config/utils.go (1)

11-11: LGTM: New import for enhanced error handling

The addition of the logger package import aligns with the PR objectives of enhancing error handling. This change will allow for more structured and informative error reporting.

pkg/logger/logger.go Outdated Show resolved Hide resolved
pkg/logger/logger.go Outdated Show resolved Hide resolved
pkg/logger/logger.go Outdated Show resolved Hide resolved
cmd/root.go Outdated
Comment on lines 75 to 76
// Set the log level for IError interface
logger.SetPrintDebugPart(cliConfig.Logs.Level)
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

LGTM: Setting log level for IError interface.

The new line correctly sets the log level for the IError interface using the CLI configuration. This aligns with the PR objective of enhancing error handling and adjusting log levels.

However, consider adding error handling for the SetPrintDebugPart function call to ensure robustness.

Consider updating the code as follows:

 // Set the log level for IError interface
-logger.SetPrintDebugPart(cliConfig.Logs.Level)
+if err := logger.SetPrintDebugPart(cliConfig.Logs.Level); err != nil {
+    u.LogErrorAndExit(err)
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Set the log level for IError interface
logger.SetPrintDebugPart(cliConfig.Logs.Level)
// Set the log level for IError interface
if err := logger.SetPrintDebugPart(cliConfig.Logs.Level); err != nil {
u.LogErrorAndExit(err)
}

pkg/config/utils.go Outdated Show resolved Hide resolved
pkg/config/utils.go Outdated Show resolved Hide resolved
Copy link
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: 6

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 2bc991d and a08d257.

📒 Files selected for processing (4)
  • cmd/root.go (1 hunks)
  • pkg/config/const.go (1 hunks)
  • pkg/config/utils.go (2 hunks)
  • pkg/utils/log_utils.go (3 hunks)
🧰 Additional context used
🔇 Additional comments (2)
pkg/config/const.go (1)

71-71: LGTM: New constant added for CLI configuration prefix

The addition of CliConfigPrefix constant with the value "CLI config:" is consistent with the existing naming conventions and appears to be a logical extension of the configuration constants. This prefix will likely be used for logging or output formatting related to CLI configurations.

A few points to consider:

  1. The constant follows the existing naming convention (PascalCase for exported constants).
  2. Its purpose seems clear and aligned with other constants in this file.
  3. The value is a simple string, which doesn't pose any immediate security concerns.

To ensure this constant is being used appropriately, let's check its usage across the codebase:

This will help verify that the constant is being utilized as intended and that its introduction doesn't cause any conflicts.

✅ Verification successful

Verified: CliConfigPrefix is utilized correctly across the codebase

  • pkg/config/utils.go: Used in logging and error debug information.

No issues found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of CliConfigPrefix
rg --type go "CliConfigPrefix" --context 3

Length of output: 988

cmd/root.go (1)

74-79: LGTM: Improved log level setting with proper error handling.

The new code block effectively sets the log level for the ExtendedError interface, addressing the PR objective of enhancing error handling. Key improvements include:

  1. Conditional check ensures debug information is only set for Debug and Trace log levels.
  2. Proper error handling for SetPrintDebugPart function call, as suggested in the previous review.
  3. Consistent error handling pattern using u.LogErrorAndExit.

These changes contribute to more robust and maintainable error management in the Atmos CLI.

pkg/config/utils.go Show resolved Hide resolved
pkg/config/utils.go Show resolved Hide resolved
Comment on lines 23 to 26
var (
PrintDebugPart bool
mu sync.Mutex
)
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider encapsulating global variables PrintDebugPart and mu to avoid global state

The use of global variables PrintDebugPart and mu can lead to unintended side effects in concurrent environments and make testing more difficult. Encapsulating these variables within a struct or providing controlled access through getter and setter functions can enhance modularity and maintainability.

pkg/utils/log_utils.go Show resolved Hide resolved
Comment on lines 87 to 92
// set PrintDebugPart to true if log level is Debug or Trace
if cliConfig.Logs.Level == LogLevelDebug || cliConfig.Logs.Level == LogLevelTrace {
if setErr := SetPrintDebugPart(cliConfig.Logs.Level); setErr != nil {
color.Red("%s\n", setErr)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Initialize PrintDebugPart during startup instead of within LogError

Setting PrintDebugPart inside the LogError function causes it to be updated every time an error is logged, which can be inefficient and may introduce race conditions. It's advisable to initialize PrintDebugPart once during application startup or configuration loading to improve performance and ensure thread safety.

Comment on lines 28 to 41
// set PrintDebugPart to true if log level is Debug or Trace
func SetPrintDebugPart(val string) error {
mu.Lock()
defer mu.Unlock()
if val == "" {
return fmt.Errorf("log level not set")
}
if val == string(LogLevelDebug) || val == string(LogLevelTrace) {
PrintDebugPart = true
} else {
PrintDebugPart = false
}
return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify SetPrintDebugPart function and remove unnecessary type conversions

In the SetPrintDebugPart function, the string() type conversions are unnecessary because LogLevelDebug and LogLevelTrace are already string constants. Removing these redundant conversions simplifies the code.

Apply this diff to remove redundant type conversions:

func SetPrintDebugPart(val string) error {
	mu.Lock()
	defer mu.Unlock()
	if val == "" {
		return fmt.Errorf("log level not set")
	}
-	if val == string(LogLevelDebug) || val == string(LogLevelTrace) {
+	if val == LogLevelDebug || val == LogLevelTrace {
		PrintDebugPart = true
	} else {
		PrintDebugPart = false
	}
	return nil
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// set PrintDebugPart to true if log level is Debug or Trace
func SetPrintDebugPart(val string) error {
mu.Lock()
defer mu.Unlock()
if val == "" {
return fmt.Errorf("log level not set")
}
if val == string(LogLevelDebug) || val == string(LogLevelTrace) {
PrintDebugPart = true
} else {
PrintDebugPart = false
}
return nil
}
// set PrintDebugPart to true if log level is Debug or Trace
func SetPrintDebugPart(val string) error {
mu.Lock()
defer mu.Unlock()
if val == "" {
return fmt.Errorf("log level not set")
}
if val == LogLevelDebug || val == LogLevelTrace {
PrintDebugPart = true
} else {
PrintDebugPart = false
}
return nil
}

Copy link
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: 5

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between a08d257 and 4496b1c.

📒 Files selected for processing (2)
  • cmd/root.go (1 hunks)
  • pkg/utils/log_utils.go (3 hunks)
🧰 Additional context used
🔇 Additional comments (6)
cmd/root.go (1)

74-79: LGTM: Improved log level setting with error handling

The new code block effectively sets the log level for the ExtendedError interface, aligning with the PR objectives. Key improvements include:

  1. Checking if cliConfig.Logs.Level is not empty before attempting to set the log level.
  2. Using u.SetPrintDebugPart() to set the log level, which likely corresponds to the new IError interface mentioned in the PR objectives.
  3. Implementing error handling for the SetPrintDebugPart function call, addressing the suggestion from the previous review.

The placement of this code block is appropriate, ensuring that the log level is set after CLI configuration initialization and before processing custom commands.

pkg/utils/log_utils.go (5)

9-9: Import sync package for mutex usage

The addition of the sync package is appropriate for utilizing sync.Mutex. Ensure that all mutex usage complies with best practices for thread safety.


23-27: Avoid global variables PrintDebugPart and mu to prevent unintended side effects

Previous comment:

The use of global variables PrintDebugPart and mu can lead to unintended side effects in concurrent environments and make testing more difficult. Encapsulating these variables within a struct or providing controlled access through getter and setter functions can enhance modularity and maintainability.


43-48: Struct ExtendedError is well-defined

The ExtendedError struct effectively encapsulates both the error message and debug information.


50-56: Avoid using global state within the Error() method of ExtendedError

Previous comment:

The Error() method relies on the global variable PrintDebugPart to determine whether to include debug information. This can lead to inconsistent behavior and makes error messages dependent on external state. It's better practice for the Error() method to consistently return the error message. Consider moving the logic for including debug information to the logging functions or providing a separate method to retrieve detailed error information.


87-92: Initialize PrintDebugPart during startup instead of within LogError

Previous comment:

Setting PrintDebugPart inside the LogError function causes it to be updated every time an error is logged, which can be inefficient and may introduce race conditions. It's advisable to initialize PrintDebugPart once during application startup or configuration loading to improve performance and ensure thread safety.

pkg/utils/log_utils.go Show resolved Hide resolved
pkg/utils/log_utils.go Show resolved Hide resolved
pkg/utils/log_utils.go Show resolved Hide resolved
pkg/utils/log_utils.go Show resolved Hide resolved
pkg/utils/log_utils.go Show resolved Hide resolved
@osterman osterman changed the title Dev 340 . break error to parts Break error to parts Oct 13, 2024
@osterman osterman changed the title Break error to parts Break error into parts Oct 13, 2024
@osterman
Copy link
Member

Also update PR description to reflect changes in the code

mu sync.Mutex
)

// set PrintDebugPart to true if log level is Debug or Trace
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// set PrintDebugPart to true if log level is Debug or Trace
// SetPrintDebugPart .....

In Go, comments must start with the function name

func (e *ExtendedError) Error() string {
// Print debug info if PrintDebugPart is true
if PrintDebugPart {
return fmt.Sprintf("%s\n%s", e.Message, e.DebugInfo)
Copy link
Member

Choose a reason for hiding this comment

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

Don't use fmt.Sprintf, Atmos has many helper functions to print info, warning and error in diff colors.

These two parts e.Message and e.DebugInfo should be printed in diff colors (this is the main point of this PR)

// Set the log level for ExtendedError interface . must be set on root level to avoid missing log level
if cliConfig.Logs.Level != "" {
if err := u.SetPrintDebugPart(cliConfig.Logs.Level); err != nil {
u.LogErrorAndExit(schema.CliConfiguration{}, err)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
u.LogErrorAndExit(schema.CliConfiguration{}, err)
u.LogErrorAndExit(cliConfig, err)

We already have cliConfig, let's use it

@@ -71,7 +71,12 @@ func Execute() error {
if err != nil && !errors.Is(err, cfg.NotFound) {
u.LogErrorAndExit(schema.CliConfiguration{}, err)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
u.LogErrorAndExit(schema.CliConfiguration{}, err)
u.LogErrorAndExit(cliConfig, err)

We have cliConfig, let's use it (I missed this line in the previous PR)

Copy link
Member

@aknysh aknysh left a comment

Choose a reason for hiding this comment

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

@haitham911 the PR looks good, please address the comments

@aknysh aknysh marked this pull request as draft October 16, 2024 05:47
@aknysh aknysh changed the title Break error into parts DO NOT MERGE (needs review and testing). Break error into parts Oct 16, 2024
@aknysh aknysh added the do not merge Do not merge this PR, doing so would cause problems label Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do not merge Do not merge this PR, doing so would cause problems
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants