Handle all user errors in add_subscription_dialog

This commit is contained in:
ranfdev
2023-10-24 18:44:25 +02:00
parent 98a6a0ad47
commit 933247e564
6 changed files with 92 additions and 48 deletions

View File

@ -21,6 +21,8 @@ pub struct SharedEnv {
pub enum Error {
#[error("topic {0} must not be empty and must contain only alphanumeric characters and _ (underscore)")]
InvalidTopic(String),
#[error("invalid server base url {0:?}")]
InvalidServer(#[from] url::ParseError),
#[error("duplicate message")]
DuplicateMessage,
#[error("can't parse the minimum set of required fields from the message {0}")]

View File

@ -121,23 +121,31 @@ pub struct Subscription {
}
impl Subscription {
pub fn build_url(server: &str, topic: &str, since: u64) -> anyhow::Result<url::Url> {
pub fn build_url(server: &str, topic: &str, since: u64) -> Result<url::Url, crate::Error> {
let mut url = url::Url::parse(server)?;
url.path_segments_mut()
.map_err(|_| anyhow::anyhow!("url can't be base"))?
.map_err(|_| url::ParseError::RelativeUrlWithCannotBeABaseBase)?
.push(&topic)
.push("json");
url.query_pairs_mut()
.append_pair("since", &since.to_string());
Ok(url)
}
pub fn validate(self) -> anyhow::Result<Self> {
validate_topic(&self.topic)?;
Self::build_url(&self.server, &self.topic, 0)?;
pub fn validate(self) -> Result<Self, Vec<crate::Error>> {
let mut errs = vec![];
if let Err(e) = validate_topic(&self.topic) {
errs.push(e);
};
if let Err(e) = Self::build_url(&self.server, &self.topic, 0) {
errs.push(e);
};
if errs.len() > 0 {
return Err(errs);
}
Ok(self)
}
pub fn builder(server: String, topic: String) -> SubscriptionBuilder {
SubscriptionBuilder::new(server, topic)
pub fn builder(topic: String) -> SubscriptionBuilder {
SubscriptionBuilder::new(topic)
}
}
@ -153,9 +161,9 @@ pub struct SubscriptionBuilder {
}
impl SubscriptionBuilder {
pub fn new(server: String, topic: String) -> Self {
pub fn new(topic: String) -> Self {
Self {
server,
server: "https://ntfy.sh".to_string(),
topic,
muted: false,
archived: false,
@ -165,6 +173,11 @@ impl SubscriptionBuilder {
}
}
pub fn server(mut self, server: String) -> Self {
self.server = server;
self
}
pub fn muted(mut self, muted: bool) -> Self {
self.muted = muted;
self
@ -190,7 +203,7 @@ impl SubscriptionBuilder {
self
}
pub fn build(self) -> anyhow::Result<Subscription> {
pub fn build(self) -> Result<Subscription, Vec<Error>> {
let res = Subscription {
server: self.server,
topic: self.topic,

View File

@ -401,17 +401,11 @@ impl system_notifier::Server for SystemNotifier {
) -> capnp::capability::Promise<(), capnp::Error> {
let topic = pry!(pry!(params.get()).get_topic());
let server: &str = pry!(pry!(params.get()).get_server());
let server = if server.is_empty() {
"https://ntfy.sh"
} else {
""
};
let subscription = pry!(
models::Subscription::builder(server.to_owned(), topic.to_owned())
.build()
.map_err(|e| capnp::Error::failed(e.to_string()))
);
let subscription = pry!(models::Subscription::builder(topic.to_owned())
.server(server.to_string())
.build()
.map_err(|e| capnp::Error::failed(format!("{:?}", e))));
let sub: Promise<subscription::Client, capnp::Error> = self.watch(subscription.clone());
let mut db = self.env.db.clone();