Improve unknown link error

This commit is contained in:
Damir Modyarov 2023-08-07 23:00:41 +03:00
parent 0505f63a9c
commit 44982a1190
2 changed files with 37 additions and 9 deletions

View File

@ -1,12 +1,12 @@
from typing import Annotated
import django
from fastapi import FastAPI, Depends, HTTPException, Header
from fastapi.responses import RedirectResponse
from fastapi import FastAPI, Depends, Header
from fastapi.responses import RedirectResponse, HTMLResponse
from sqlalchemy.orm import Session
from starlette.requests import Request
from redirect.db.curd import get_link_by_slug
from redirect.db.curd import get_link_by_slug, LinkNotFoundException
from redirect.db.dependency import get_db
@ -17,6 +17,32 @@
from akarpov.tools.shortener.tasks import save_view_meta # noqa: This has to be imported strictly AFTER django setup
@app.exception_handler(LinkNotFoundException)
async def unicorn_exception_handler(request: Request, exc: LinkNotFoundException):
return HTMLResponse(
status_code=404,
# language=HTML
content="""
<html lang="en">
<head>
<title>Unknown Link</title>
<style>
h1 {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", ui-system, sans-serif;
font-weight: bold;
font-size: medium;
text-align: center;
}
</style>
</head>
<body>
<h1>Such link doesn't exist or has been revoked</h1>
</body>
</html>
""",
)
@app.get("/{slug}")
def redirect(slug: str, request: Request, db: Session = Depends(get_db), user_agent: Annotated[str | None, Header()] = None) -> RedirectResponse:
"""Main route that redirects to a page based on the slug."""
@ -24,8 +50,6 @@ def redirect(slug: str, request: Request, db: Session = Depends(get_db), user_ag
return RedirectResponse(url=f'/tools/shortener/p/{slug.replace("+", "")}')
link = get_link_by_slug(db, slug)
if link is None:
raise HTTPException(status_code=404, detail="Unknown Short Link")
save_view_meta.apply_async(
kwargs={

View File

@ -1,11 +1,14 @@
from typing import Optional
from sqlalchemy.orm import Session
from redirect.db import models
from redirect.util import slug_to_link_id
class LinkNotFoundException(Exception):
def __init__(self, slug: str):
self.slug = slug
def get_link(db: Session, link_id: int):
"""Gets short link metdata by its id.
@ -19,19 +22,20 @@ def get_link(db: Session, link_id: int):
_get_link_by_slug_cache = {}
def get_link_by_slug(db: Session, slug: str) -> Optional[tuple[int, str]]:
def get_link_by_slug(db: Session, slug: str) -> tuple[int, str]:
"""Converts slug to id and gets related link target.
:param db Open connection to a database
:param slug of the link
:raise LinkNotFoundException if link is not found
:return target link id & url"""
if slug in _get_link_by_slug_cache:
return _get_link_by_slug_cache[slug]
link = get_link(db, slug_to_link_id(slug))
if link is None or not link.enabled:
return None
raise LinkNotFoundException(slug)
_get_link_by_slug_cache[slug] = (link.id, link.source)
return link.id, link.source