Skip to content

feat: better error message for having no env file#15

Merged
QuantumExplorer merged 4 commits into
masterfrom
feat/better-error-for-no-env-file
Oct 22, 2024
Merged

feat: better error message for having no env file#15
QuantumExplorer merged 4 commits into
masterfrom
feat/better-error-for-no-env-file

Conversation

@pauldelucia
Copy link
Copy Markdown
Member

@pauldelucia pauldelucia commented Oct 22, 2024

Summary by CodeRabbit

  • Bug Fixes
    • Improved error handling for configuration loading, ensuring the application does not proceed with invalid configurations.
    • Added a specific error message for failed configuration loads.
  • New Features
    • Introduced a new error handling mechanism for configuration loading, including specific error types for load failures.
    • Enhanced initialization process to manage errors more gracefully when setting up application context.
    • Updated the network chooser to inform users when no testnet configurations are available.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 22, 2024

Walkthrough

The changes introduce a new error handling mechanism in the load method of the Config struct within the src/config.rs file. A conditional check has been added to verify the successful loading of mainnet_config and testnet_config. If both configurations are None, the method returns a ConfigError::NoValidConfigs. Additionally, the AppState::new and AppContext::new methods in src/app.rs and src/context.rs, respectively, have been updated to enhance error handling during initialization. The NetworkChooserScreen struct in src/ui/network_chooser_screen.rs has also been modified to improve user feedback and error handling related to network configurations.

Changes

File Change Summary
src/config.rs Introduced ConfigError enum with variants for loading errors. Updated load method to return Result<Self, ConfigError>. Added error handling for configuration loading failures.
src/app.rs Modified AppState::new to use a match statement for initializing mainnet_app_context, replacing expect with error handling.
src/context.rs Updated AppContext::new to include error handling for configuration loading using a match statement.
src/ui/network_chooser_screen.rs Updated NetworkChooserScreen::new to use testnet_app_context.cloned(). Enhanced render_network_row with a check for None configurations. Improved error handling in start_dash_qt.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant Config

    App->>Config: Call load()
    Config-->>App: Load mainnet_config
    Config-->>App: Load testnet_config
    alt Configurations are valid
        App->>Config: Proceed with application
    else Configurations are invalid
        Config-->>App: Return ConfigError::NoValidConfigs
    end
Loading

Poem

In the code where configs dwell,
A new check rings a warning bell.
If the load goes awry,
An error will cry,
"Invalid configs, all is not well!" 🐰✨


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
Copy Markdown
Contributor

@ogabrielides ogabrielides left a comment

Choose a reason for hiding this comment

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

utACK

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: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between f0ec118 and 7fd26b9.

📒 Files selected for processing (1)
  • src/config.rs (1 hunks)
🧰 Additional context used
🔇 Additional comments (1)
src/config.rs (1)

86-89: Verify usage of Config::load() in the codebase

The new error handling mechanism changes the behavior of Config::load(). Ensure that all calls to this method throughout the codebase are updated to handle the potential panic or, if you implement the suggested Result return type, to properly handle the potential error case.

Run the following script to find all usages of Config::load():

Review the output to ensure that all usages of Config::load() are updated to handle the new error case appropriately.

Comment thread src/config.rs Outdated
Comment on lines +86 to +89
if mainnet_config.is_none() || testnet_config.is_none() {
panic!("Configs could not be properly loaded from .env file or environment variables")
}

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.

🛠️ Refactor suggestion

⚠️ Potential issue

Consider improving the error handling mechanism

While the new check ensures both configurations are loaded, using panic! might be too drastic. Consider the following improvements:

  1. Return a Result<Self, ConfigError> instead of panicking, allowing for more graceful error handling:
pub fn load() -> Result<Self, ConfigError> {
    // ... (existing code)

    if mainnet_config.is_none() && testnet_config.is_none() {
        return Err(ConfigError::NoValidConfigs);
    }

    Ok(Config {
        mainnet_config,
        testnet_config,
    })
}
  1. Provide more specific error information:
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
    #[error("Failed to load configurations: {0}")]
    LoadError(String),
    #[error("No valid network configurations found")]
    NoValidConfigs,
}

// In the `load` function:
if mainnet_config.is_none() && testnet_config.is_none() {
    return Err(ConfigError::NoValidConfigs);
} else if mainnet_config.is_none() {
    return Err(ConfigError::LoadError("Failed to load mainnet configuration".into()));
} else if testnet_config.is_none() {
    return Err(ConfigError::LoadError("Failed to load testnet configuration".into()));
}
  1. Consider allowing the application to run with at least one valid network configuration, if that's acceptable for your use case.

These changes would improve error handling, make debugging easier, and provide more flexibility in how errors are handled by the calling code.

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

🧹 Outside diff range and nitpick comments (2)
src/config.rs (1)

94-109: LGTM: Comprehensive error handling with a minor suggestion.

The new error handling logic is a significant improvement. It ensures that at least one valid network configuration is present and provides specific error messages for different scenarios. This addresses the concerns raised in the previous review.

Consider simplifying the logic slightly:

if mainnet_config.is_none() && testnet_config.is_none() {
    return Err(ConfigError::NoValidConfigs);
} else if mainnet_config.is_none() {
    return Err(ConfigError::LoadError("Failed to load mainnet configuration".into()));
} else if testnet_config.is_none() {
    return Err(ConfigError::LoadError("Failed to load testnet configuration".into()));
}

Ok(Config {
    mainnet_config,
    testnet_config,
})

This removes the need for the extra else block and makes the code slightly more concise.

src/app.rs (1)

107-115: Improved error handling, but consider further enhancements.

The introduction of explicit error handling for AppContext::new is a good improvement over using expect or unwrap. It provides a more graceful way to handle failures and exit the program.

However, consider the following suggestions:

  1. Enhance the error message to include more details about why the context creation failed. This could be achieved by modifying the AppContext::new method to return a Result with a detailed error message.
  2. For consistency, update the error handling for the testnet context creation (line 116) to match this new pattern.
  3. Consider if there's a more graceful way to handle this failure. Instead of exiting the program immediately, you might want to provide options for the user to retry or proceed with limited functionality.

Here's a potential improvement:

let mainnet_app_context = match AppContext::new(Network::Dash, db.clone()) {
    Some(context) => context,
    None => {
        eprintln!(
            "Error: Failed to create the AppContext for mainnet. Please check your configuration and try again."
        );
        // Consider returning a Result from this function instead of exiting
        return Err(ConfigError::MainnetContextCreationFailed);
    }
};

// Apply similar pattern for testnet
let testnet_app_context = match AppContext::new(Network::Testnet, db.clone()) {
    Some(context) => Some(context),
    None => {
        eprintln!(
            "Warning: Failed to create the AppContext for testnet. Testnet functionality will be unavailable."
        );
        None
    }
};

This approach provides more detailed error messages and handles the testnet case consistently. It also allows for more flexible error handling in the calling code.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 7fd26b9 and d2197c3.

📒 Files selected for processing (3)
  • src/app.rs (1 hunks)
  • src/config.rs (3 hunks)
  • src/context.rs (1 hunks)
🧰 Additional context used
🔇 Additional comments (3)
src/config.rs (3)

28-34: LGTM: Well-structured error handling.

The addition of the ConfigError enum with specific error variants improves error handling and provides clear, descriptive error messages. The use of thiserror::Error is a good practice in Rust for defining custom errors.


60-60: LGTM: Improved error handling in load method.

The change in the load method signature to return a Result<Self, ConfigError> instead of Self is a significant improvement. It allows for more graceful error handling and provides better information to the caller about potential configuration loading issues.


Line range hint 28-109: Great improvements in error handling and configuration management!

The changes in this file significantly enhance the robustness of the configuration loading process. The introduction of the ConfigError enum, the updated load method signature, and the more detailed error handling logic all contribute to better error reporting and easier debugging. These improvements align well with Rust best practices and address the concerns raised in the previous review.

Comment thread src/context.rs
Comment on lines +38 to +44
let config = match Config::load() {
Ok(config) => config,
Err(e) => {
println!("Failed to load config: {e}");
return None;
}
};
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.

💡 Codebase verification

Inconsistent handling of None when loading Testnet config. Ensure that AppContext::new() failure is handled appropriately.

  • Consider handling None for testnet_app_context similarly to mainnet_app_context.
🔗 Analysis chain

Improved error handling for config loading. Consider enhancing error reporting.

The addition of error handling for Config::load() is a good improvement. It prevents the application from proceeding with an invalid configuration.

Consider using a proper logging mechanism instead of println! for error reporting. This would provide more flexibility in how errors are handled and logged in different environments.

Example:

use log::error;

// ...

Err(e) => {
    error!("Failed to load config: {}", e);
    return None;
}

Let's verify the impact of returning None when config loading fails:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how `None` is handled when `AppContext::new()` is called

# Search for calls to AppContext::new and their error handling
rg -n "AppContext::new\(" -A 10

Length of output: 1319

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: 0

🧹 Outside diff range and nitpick comments (3)
src/config.rs (1)

Line range hint 60-105: Improved error handling in Config::load

The changes to Config::load significantly improve error handling, aligning with best practices and the previous suggestions. The method now returns a Result and properly handles configuration loading errors.

Consider adding a check for the case where only the testnet configuration is missing:

if mainnet_config.is_none() && testnet_config.is_none() {
    return Err(ConfigError::NoValidConfigs);
} else if mainnet_config.is_none() {
    return Err(ConfigError::LoadError(
        "Failed to load mainnet configuration".into(),
    ));
} else if testnet_config.is_none() {
    return Err(ConfigError::LoadError(
        "Failed to load testnet configuration".into(),
    ));
}

This addition would provide more specific error information when only the testnet configuration fails to load.

src/ui/network_chooser_screen.rs (2)

119-123: Good addition of user feedback for missing testnet configs

This change improves the user experience by explicitly showing when testnet configurations are not loaded. It aligns well with the PR objective of providing better error messages.

Consider using a more descriptive constant for the label text to improve maintainability:

+ const NO_TESTNET_CONFIG_LABEL: &str = "(No configs for testnet loaded)";

 if network == Network::Testnet && self.testnet_app_context.is_none() {
-    ui.label("(No configs for testnet loaded)");
+    ui.label(NO_TESTNET_CONFIG_LABEL);
     return AppAction::None;
 }

Line range hint 189-195: Improved error handling for missing Dash-Qt binary

Great addition of a check for the existence of the Dash-Qt binary before attempting to start it. This provides a more specific error message when the binary is missing, which aligns with the PR objective of enhancing error messages.

For consistency with the rest of the codebase, consider using a custom error type instead of io::Error:

#[derive(Debug, thiserror::Error)]
enum DashQtError {
    #[error("Dash-Qt not found at: {0}")]
    BinaryNotFound(PathBuf),
    // Add other error variants as needed
}

// In the start_dash_qt method:
if !dash_qt_path.exists() {
    return Err(DashQtError::BinaryNotFound(dash_qt_path).into());
}

This approach would provide more type-safety and allow for easier error handling and matching in the calling code.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d2197c3 and d88614b.

📒 Files selected for processing (2)
  • src/config.rs (3 hunks)
  • src/ui/network_chooser_screen.rs (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
src/config.rs (2)

28-34: LGTM: Well-defined error enum

The ConfigError enum is well-implemented, providing specific error types for configuration loading issues. The use of thiserror::Error and clear error messages enhances error handling and debugging.


Line range hint 1-134: Overall improvements to configuration error handling

The changes in this file significantly enhance the error handling mechanism for configuration loading. The introduction of the ConfigError enum and the modifications to the Config::load method align with Rust best practices and improve the robustness of the application.

These changes address the concerns raised in previous reviews and provide a more graceful way of handling configuration errors. The code is now more maintainable and provides better feedback in case of configuration issues.

src/ui/network_chooser_screen.rs (2)

Line range hint 28-41: LGTM: Improved cloning of optional context

The change from clone() to cloned() for testnet_app_context is a good improvement. It's more idiomatic for Option<&T> types and only clones the inner value if it exists.


Line range hint 1-280: Overall assessment: Improvements align well with PR objectives

The changes in this file successfully enhance error handling and user feedback, particularly for missing testnet configurations and Dash-Qt binary. These improvements align well with the PR objective of providing better error messages.

Key improvements:

  1. More efficient cloning of optional testnet context
  2. Clear feedback for missing testnet configurations
  3. Improved error handling for missing Dash-Qt binary

The suggested minor improvements (using a constant for the label text and a custom error type) would further enhance code maintainability and consistency. Overall, good job on improving the user experience and error handling in the NetworkChooserScreen.

@QuantumExplorer QuantumExplorer merged commit 0b155a2 into master Oct 22, 2024
@QuantumExplorer QuantumExplorer deleted the feat/better-error-for-no-env-file branch October 22, 2024 11:26
@coderabbitai coderabbitai Bot mentioned this pull request Mar 11, 2025
shumkov added a commit that referenced this pull request Apr 13, 2026
Add wallet_id BLOB column to dashpay_profiles, dashpay_contacts,
and dashpay_contact_requests schemas. Write paths store wallet_id.
Load paths filter by wallet_id.

Same pattern as the dashpay_payments fix (Critical #2). No migration
needed — v40 already nuked all data in these tables. The fresh-
install schema now includes the column.

This prevents cross-wallet data contamination: loading wallet A no
longer sees profiles, contacts, or contact requests from wallet B.

Co-Authored-By: Claude Opus 4.6 (1M context) <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.

3 participants