Files
n34/src/error.rs
Awiteb 904d14064f feat: Sign using NIP-07
Signed-off-by: Awiteb <a@4rs.nl>
2025-08-07 23:22:40 +00:00

170 lines
6.5 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// n34 - A CLI to interact with NIP-34 and other stuff related to codes in nostr
// Copyright (C) 2025 Awiteb <a@4rs.nl>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://gnu.org/licenses/gpl-3.0.html>.
use std::{net::AddrParseError, process::ExitCode};
use nostr::{
event::{Kind, builder::Error as EventBuilderError},
signer::SignerError,
};
use nostr_sdk::client::Error as ClientError;
use crate::cli::ConfigError;
/// The input data was incorrect in some way. This should only be used for
/// users data and not system file.
const DATA_ERROR: u8 = 65;
/// An internal software error has been detected. This should be limited to
/// non-operating system related errors.
const SOFTWARE_ERROR: u8 = 70;
/// An error occurred while doing I/O on some file.
const IO_ERROR: u8 = 74;
/// Something was found in an unconfigured or misconfigured state.
const CONFIG_ERROR: u8 = 78;
pub type N34Result<T> = Result<T, N34Error>;
/// N34 errors
#[derive(Debug, thiserror::Error)]
pub enum N34Error {
#[error("IO: {0}")]
Io(#[from] std::io::Error),
#[error("Signer Error: {0}")]
SignerError(#[from] SignerError),
#[error("Invalid Browser Signer Proxy Address: {0}")]
Addr(#[from] AddrParseError),
#[error("Browser Signer Proxy Error: {0}")]
BrowserSignerProxy(#[from] nostr_browser_signer_proxy::Error),
#[error("Keyring error: {0}")]
Keyring(#[from] nostr_keyring::Error),
#[error("{0}")]
Config(#[from] ConfigError),
#[error("No editor specified in the `EDITOR` environment variable")]
EditorNotFound,
#[error("The file you edited is empty. Please save your changes before exiting the editor.")]
EmptyEditorFile,
#[error("The editor `{0}` exit with unsuccessful exit code `{1}`")]
EditorErr(String, i32),
#[error("Client Error: {0}")]
Client(#[from] ClientError),
#[error("Unable to locate the repository. The repository may not exists in the given relays")]
NotFoundRepo,
#[error("Failed building an event: {0}")]
EventBuilder(#[from] EventBuilderError),
#[error("Invalid repository id, it can't be empty and must be kebab-case")]
InvalidRepoId,
#[error("Invalid event: {0}")]
InvalidEvent(String),
#[error("Bech32 error: {0}")]
Bech32(#[from] nostr::nips::nip19::Error),
#[error("Event error: {0}")]
Event(#[from] nostr::event::Error),
#[error("Event not found in the specified relays")]
EventNotFound,
#[error(
"Can't reply to this event. Only Git issues, patches, and their comments can be replied \
to."
)]
CanNotReplyToEvent,
#[error("No repository address given and couldn't read `nostr-address` file: {0}")]
CanNotReadNostrAddressFile(std::io::Error),
#[error(
"The `nostr-address` file is empty. Please add a valid Nostr repository address (naddr) \
to the file or provide it manually as a flag."
)]
EmptyNostrAddressFile,
#[error("Invalid `nostr-address` file content: {0}")]
InvalidNostrAddressFileContent(String),
#[error("This command requires at least one relay, but none were provided")]
EmptyRelays,
#[error("One naddr is required for this command")]
EmptyNaddrs,
#[error(
"This command requires a signer to sign events. Use `--secret-key`, `--nip07` or \
`--bunker-url` to provide a signer"
)]
SignerRequired,
#[error(
"Invalid repository address. Expected one of these formats:\n- NIP-05 identifier with \
repository ID: `<user@domain.com>/<repo_id>`\n- Valid NIP-19 naddr string (starts with \
'naddr1...')\n- Existing set name (merges all repositories in set)\nError: No set named \
'{0}' exists."
)]
InvalidNaddrArg(String),
#[error(
"Invalid relays. Expected a relay url or a set name that contains some relays\nError: No \
set named '{0}' exists."
)]
InvalidRelaysArg(String),
#[error(
"The set '{0}' doesn't contain any addresses. Use 'sets update' to add addresses to it."
)]
EmptySetNaddrs(String),
#[error("The set '{0}' doesn't contain any relays. Use 'sets update' to add relays to it.")]
EmptySetRelays(String),
#[error(
"Issue not found, make sure it is in the relays and make sure that the ID is an issue ID"
)]
CanNotFoundIssue,
#[error(
"Patch not found, make sure it is in the relays and make sure that the ID is an patch ID"
)]
CanNotFoundPatch,
#[error(r#"The given patch id is not a root patch. It must contains `["t", "root"]` tag"#)]
NotRootPatch,
#[error("This status kind can't be set for an issue: {0}")]
InvalidIssueStatus(Kind),
#[error("This status kind can't be set for a patch: {0}")]
InvalidPatchStatus(Kind),
#[error("Can't find the root patch of the given patch-revision")]
RevisionRootNotFound,
#[error("Invalid status for the issue/patch: {0}")]
InvalidStatus(String),
#[error("Not valid bunker URL")]
NotBunkerUrl,
#[error(
"No secret key found in the keyring. Please use the secret key at least once while \
keyring is enabled to store it"
)]
SecretKeyKeyringWithoutEntry,
}
impl N34Error {
/// Returns the exit code associated with this error
pub fn exit_code(&self) -> ExitCode {
match self {
Self::Io(_) | Self::CanNotReadNostrAddressFile(_) => ExitCode::from(IO_ERROR),
Self::Config(_) => ExitCode::from(CONFIG_ERROR),
Self::EditorErr(..) => ExitCode::from(SOFTWARE_ERROR),
Self::InvalidRepoId
| Self::EmptyNostrAddressFile
| Self::InvalidNostrAddressFileContent(_)
| Self::EmptyRelays
| Self::EmptyNaddrs
| Self::SignerRequired
| Self::InvalidNaddrArg(_)
| Self::InvalidRelaysArg(_)
| Self::EmptySetNaddrs(_)
| Self::EmptySetRelays(_)
| Self::NotRootPatch => ExitCode::from(DATA_ERROR),
_ => ExitCode::FAILURE,
}
}
}