diff --git a/src/core/error.rs b/src/core/error.rs index dc88892..351a3b5 100644 --- a/src/core/error.rs +++ b/src/core/error.rs @@ -150,27 +150,49 @@ impl GiError { Self::Io(_) => ErrorCode::IoError, Self::Transform(_) => ErrorCode::TransformError, Self::NotFound(_) => ErrorCode::GitLabNotFound, - Self::Ambiguous(_) => ErrorCode::InternalError, + Self::Ambiguous(_) => ErrorCode::GitLabNotFound, Self::Other(_) => ErrorCode::InternalError, } } - /// Get a suggestion for how to fix this error. + /// Get a suggestion for how to fix this error, including inline examples. pub fn suggestion(&self) -> Option<&'static str> { match self { - Self::ConfigNotFound { .. } => Some("Run 'lore init' to create configuration"), - Self::ConfigInvalid { .. } => Some("Check config file syntax or run 'lore init' to recreate"), - Self::GitLabAuthFailed => Some("Verify token has read_api scope and is not expired"), - Self::GitLabNotFound { .. } => Some("Check the resource path exists and you have access"), + Self::ConfigNotFound { .. } => Some( + "Run 'lore init' to set up your GitLab connection.\n\n Expected: ~/.config/lore/config.json", + ), + Self::ConfigInvalid { .. } => Some( + "Check config file syntax or run 'lore init' to recreate.\n\n Example:\n lore init\n lore init --force", + ), + Self::GitLabAuthFailed => Some( + "Verify token has read_api scope and is not expired.\n\n Example:\n export GITLAB_TOKEN=glpat-xxxxxxxxxxxx\n lore auth", + ), + Self::GitLabNotFound { .. } => Some( + "Check the resource path exists and you have access.\n\n Example:\n lore issues -p group/project\n lore mrs -p group/project", + ), Self::GitLabRateLimited { .. } => Some("Wait and retry, or reduce request frequency"), - Self::GitLabNetworkError { .. } => Some("Check network connection and GitLab URL"), - Self::DatabaseLocked { .. } => Some("Wait for other sync to complete or use --force"), - Self::MigrationFailed { .. } => Some("Check database file permissions or reset with 'lore reset'"), - Self::TokenNotSet { .. } => Some("Export the token environment variable"), - Self::Database(_) => Some("Check database file permissions or reset with 'lore reset'"), + Self::GitLabNetworkError { .. } => Some( + "Check network connection and GitLab URL.\n\n Example:\n lore doctor\n lore auth", + ), + Self::DatabaseLocked { .. } => Some( + "Wait for other sync to complete or use --force.\n\n Example:\n lore ingest --force\n lore ingest issues --force", + ), + Self::MigrationFailed { .. } => Some( + "Check database file permissions or reset with 'lore reset'.\n\n Example:\n lore migrate\n lore reset --yes", + ), + Self::TokenNotSet { .. } => Some( + "Export the token to your shell:\n\n export GITLAB_TOKEN=glpat-xxxxxxxxxxxx\n\n Your token needs the read_api scope.", + ), + Self::Database(_) => Some( + "Check database file permissions or reset with 'lore reset'.\n\n Example:\n lore doctor\n lore reset --yes", + ), Self::Http(_) => Some("Check network connection"), - Self::NotFound(_) => Some("Verify the entity exists using 'lore list'"), - Self::Ambiguous(_) => Some("Use --project flag to disambiguate"), + Self::NotFound(_) => Some( + "Verify the entity exists.\n\n Example:\n lore issues\n lore mrs", + ), + Self::Ambiguous(_) => Some( + "Use -p to choose a specific project.\n\n Example:\n lore issues 42 -p group/project-a\n lore mrs 99 -p group/project-b", + ), _ => None, } }