Skip to content

Commit

Permalink
chore: improve error message when local replica not running (#3973)
Browse files Browse the repository at this point in the history
  • Loading branch information
sesi200 authored Nov 5, 2024
1 parent 6034fa2 commit a4ca210
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# UNRELEASED

### chore: improve error message when trying to use the local replica when it is not running

### Frontend canister

Allow setting permissions lists in init arguments just like in upgrade arguments.
Expand Down
10 changes: 10 additions & 0 deletions e2e/tests-dfx/error_context.bash
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,13 @@ teardown() {
assert_contains "it did not contain a function that dfx was looking for"
assert_contains "dfx identity set-wallet <PRINCIPAL> --identity <IDENTITY>"
}

@test "Local replica not running has nice error messages" {
dfx_new
assert_command_fail dfx ping local
assert_contains "You are trying to connect to the local replica but dfx cannot connect to it."
assert_command_fail dfx deploy
assert_contains "You are trying to connect to the local replica but dfx cannot connect to it."
assert_command_fail dfx canister call um5iw-rqaaa-aaaaq-qaaba-cai some_method
assert_contains "You are trying to connect to the local replica but dfx cannot connect to it."
}
42 changes: 42 additions & 0 deletions src/dfx/src/lib/diagnosis.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::lib::error_code;
use anyhow::Error as AnyhowError;
use dfx_core::error::root_key::FetchRootKeyError;
use ic_agent::agent::{RejectCode, RejectResponse};
use ic_agent::AgentError;
use ic_asset::error::{GatherAssetDescriptorsError, SyncError, UploadContentError};
Expand Down Expand Up @@ -55,6 +56,10 @@ pub fn diagnose(err: &AnyhowError) -> Diagnosis {
}
}

if local_replica_not_running(err) {
return diagnose_local_replica_not_running();
}

if let Some(sync_error) = err.downcast_ref::<SyncError>() {
if duplicate_asset_key_dist_and_src(sync_error) {
return diagnose_duplicate_asset_key_dist_and_src();
Expand All @@ -64,6 +69,32 @@ pub fn diagnose(err: &AnyhowError) -> Diagnosis {
NULL_DIAGNOSIS
}

fn local_replica_not_running(err: &AnyhowError) -> bool {
let maybe_agent_error = {
if let Some(FetchRootKeyError::AgentError(agent_error)) =
err.downcast_ref::<FetchRootKeyError>()
{
Some(agent_error)
} else {
err.downcast_ref::<AgentError>()
}
};
if let Some(AgentError::TransportError(transport_error)) = maybe_agent_error {
transport_error.is_connect()
&& transport_error
.url()
.and_then(|url| url.host())
.map(|host| match host {
url::Host::Domain(domain) => domain == "localhost",
url::Host::Ipv4(ipv4_addr) => ipv4_addr.is_loopback(),
url::Host::Ipv6(ipv6_addr) => ipv6_addr.is_loopback(),
})
.unwrap_or(false)
} else {
false
}
}

fn not_a_controller(err: &AgentError) -> bool {
// Newer replicas include the error code in the reject response.
if matches!(
Expand Down Expand Up @@ -119,6 +150,17 @@ The most common way this error is solved is by running 'dfx canister update-sett
)
}

fn diagnose_local_replica_not_running() -> Diagnosis {
let error_explanation =
"You are trying to connect to the local replica but dfx cannot connect to it.";
let action_suggestion =
"Target a different network or run 'dfx start' to start the local replica.";
(
Some(error_explanation.to_string()),
Some(action_suggestion.to_string()),
)
}

fn subnet_not_authorized() -> Diagnosis {
let action_suggestion = "If you are connecting to a node directly instead of a boundary node, try using --provisional-create-canister-effective-canister-id with a canister id in the subnet's canister range. First non-root subnet: 5v3p4-iyaaa-aaaaa-qaaaa-cai, second non-root subnet: jrlun-jiaaa-aaaab-aaaaa-cai";
(None, Some(action_suggestion.to_string()))
Expand Down

0 comments on commit a4ca210

Please sign in to comment.