Skip to content

Commit

Permalink
feat: Add error handling and link click tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
ikurotime committed Jan 8, 2024
1 parent b7a74df commit 28a62d6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
7 changes: 6 additions & 1 deletion assets/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
@apply bg-background text-foreground;
}
}

.error-message {
color: red;
}
.error input {
box-shadow: 0 0 3px #cc0000;
}
.animate-in {
animation: animateIn 0.3s ease 0.15s both;
}
Expand Down
26 changes: 22 additions & 4 deletions src/routes/link_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
use axum::{routing::post, Extension, Form, Router};
use rand;
use rand::Rng;
use serde::Deserialize;
use sqlx::{Error, PgPool, Row};

pub fn get_routes() -> Router {
Expand All @@ -15,18 +16,31 @@ async fn add_link(
ctx: Extension<ApiContext>,
Form(payload): Form<LinkRequest>,
) -> Result<String, String> {
if payload.original_url.is_empty() {
return Err("<div class=\"p-2 animate-in text-red-900 bg-red-300 border-2 border-red-600\">Please enter an URL</div>".to_string());
}
if payload.path.len() > 0 && payload.path.len() < 5 {
return Err("<div class=\"p-2 animate-in text-red-900 bg-red-300 border-2 border-red-600\">Path must be at least 5 characters long</div>".to_string());
}
if payload.original_url.len() > 200 {
return Err("<div class=\"p-2 animate-in text-red-900 bg-red-300 border-2 border-red-600\">URL must be less than 200 characters long</div>".to_string());
}
if !payload.original_url.starts_with("http://") || !payload.original_url.starts_with("https://")
{
return Err("<div class=\"p-2 animate-in text-red-900 bg-red-300 border-2 border-red-600\">URL must start with http:// or https://</div>".to_string());
}
// Store the links in the database
let link = match insert_link(&payload, &ctx.db).await {
Ok(link) => link,
Err(err) => {
eprintln!("Error inserting link: {}", err);
return Err("<div class=\"p-2 animate-in text-red-900 bg-red-300 border-2 border-red-600\">Something went wrong</div>".to_string());
return Err("<div class=\"p-2 animate-in text-red-900 bg-red-300 border-2 border-red-600\">Something went wrong. Try a different path</div>".to_string());
}
};
//return html

Ok(format!(
"<div class=\"p-2 text-green-900 animate-in bg-green-300 border-2 border-green-600\">Your link: <a href=\"http://lurl.es/{}\" target=\"_blank\">https://lurl.es/{}</a></div>",
"<div class=\"p-2 text-green-900 animate-in bg-green-300 border-2 border-green-600\">Your link: <a href=\"https://lurl.es/{}\" target=\"_blank\">https://lurl.es/{}</a></div>",
link.short_url, link.short_url
))
}
Expand All @@ -38,14 +52,18 @@ async fn insert_link(payload: &LinkRequest, pool: &PgPool) -> Result<LinkRespons
};

let insertion = sqlx::query(
"INSERT INTO links (original_url, short_url) VALUES ($1, $2) RETURNING short_url",
"INSERT INTO links (original_url, short_url) VALUES ($1, $2) RETURNING id, short_url ",
)
.bind(&payload.original_url)
.bind(&path)
.fetch_one(pool)
.await?;
sqlx::query("INSERT INTO linkclicks (LinkID,ClickCount) VALUES ($1, 0)")
.bind(insertion.try_get::<i32, _>("id")?)
.execute(pool)
.await?;
let link = LinkResponse {
short_url: insertion.try_get("short_url")?,
short_url: insertion.try_get::<String, _>("short_url")?,
};
Ok(link)
}
Expand Down

0 comments on commit 28a62d6

Please sign in to comment.