From 5af2714abbe92e25edb9a696cd3546267242a20f Mon Sep 17 00:00:00 2001 From: Aykhan Shahsuvarov Date: Wed, 13 Mar 2024 17:26:30 +0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20error=20handling=20and=20l?= =?UTF-8?q?ogging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/db/cassandra.go | 12 +++++++---- app/db/postgres.go | 20 ++++++++++++------ app/errors/api.go | 9 +++++++++ app/errors/db.go | 9 +++++++++ app/http_handlers/base.go | 5 +++++ app/http_handlers/url_create.go | 36 ++++++++++++++++++++++++--------- app/main.go | 24 ++++++++++++++++++---- app/templates/index.html | 2 +- 8 files changed, 92 insertions(+), 25 deletions(-) create mode 100644 app/errors/api.go create mode 100644 app/errors/db.go diff --git a/app/db/cassandra.go b/app/db/cassandra.go index 8fbcbc4..3cafa80 100644 --- a/app/db/cassandra.go +++ b/app/db/cassandra.go @@ -1,10 +1,10 @@ package db import ( - "errors" "log" "sync" + "github.com/aykhans/oh-my-url/app/errors" "github.com/aykhans/oh-my-url/app/utils" "github.com/gocql/gocql" ) @@ -58,11 +58,11 @@ func (c *Cassandra) CreateURL(url string) (string, error) { applied, err := c.db.Query(query, id, key, url, 0).Consistency(gocql.All).MapScanCAS(m) if err != nil { log.Println(err) - return "", err + return "", errors.ErrDBCreateURL } if !applied { log.Println("Failed to insert unique key") - return "", errors.New("an error occurred, please try again later") + return "", errors.ErrDBCreateURL } c.currentID.ID = id @@ -76,7 +76,11 @@ func (c *Cassandra) GetURL(key string) (string, error) { Consistency(gocql.One). Scan(&url) if err != nil { - return "", err + log.Println(err) + if err == gocql.ErrNotFound { + return "", errors.ErrDBURLNotFound + } + return "", errors.ErrDBGetURL } return url, nil } diff --git a/app/db/postgres.go b/app/db/postgres.go index 321d644..be7a589 100644 --- a/app/db/postgres.go +++ b/app/db/postgres.go @@ -1,6 +1,9 @@ package db import ( + "log" + + "github.com/aykhans/oh-my-url/app/errors" "gorm.io/gorm" ) @@ -9,10 +12,10 @@ type Postgres struct { } type url struct { - ID uint `gorm:"primaryKey"` - Key string `gorm:"unique;not null;size:15;default:null"` - URL string `gorm:"not null;default:null"` - Count int `gorm:"not null;default:0"` + ID uint `gorm:"primaryKey"` + Key string `gorm:"unique;not null;size:15;default:null"` + URL string `gorm:"not null;default:null"` + Count int `gorm:"not null;default:0"` } func (p *Postgres) Init() { @@ -30,7 +33,8 @@ func (p *Postgres) CreateURL(mainUrl string) (string, error) { url := url{URL: mainUrl} tx := p.gormDB.Create(&url) if tx.Error != nil { - return "", tx.Error + log.Println(tx.Error) + return "", errors.ErrDBCreateURL } return url.Key, nil } @@ -39,7 +43,11 @@ func (p *Postgres) GetURL(key string) (string, error) { var result url tx := p.gormDB.Where("key = ?", key).First(&result) if tx.Error != nil { - return "", tx.Error + log.Println(tx.Error) + if tx.Error == gorm.ErrRecordNotFound { + return "", errors.ErrDBURLNotFound + } + return "", errors.ErrDBGetURL } result.Count++ p.gormDB.Save(&result) diff --git a/app/errors/api.go b/app/errors/api.go new file mode 100644 index 0000000..61ed954 --- /dev/null +++ b/app/errors/api.go @@ -0,0 +1,9 @@ +package errors + +import "errors" + +var ( + ErrAPITemplateParsing = errors.New("an error occured while parsing template please try again later") + ErrAPIInvalidURL = errors.New("invalid URL") + ErrAPI503 = errors.New("service unavailable please try again later") +) diff --git a/app/errors/db.go b/app/errors/db.go new file mode 100644 index 0000000..45938b1 --- /dev/null +++ b/app/errors/db.go @@ -0,0 +1,9 @@ +package errors + +import "errors" + +var ( + ErrDBCreateURL = errors.New("an error occured please try again later") + ErrDBGetURL = errors.New("an error occured please try again later") + ErrDBURLNotFound = errors.New("url not found") +) diff --git a/app/http_handlers/base.go b/app/http_handlers/base.go index 2731320..3167ccb 100644 --- a/app/http_handlers/base.go +++ b/app/http_handlers/base.go @@ -23,3 +23,8 @@ func InternalServerError(w http.ResponseWriter, err error) { log.Fatal(err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) } + +func Error503(w http.ResponseWriter, err error) { + log.Println(err) + http.Error(w, "Service Unavailable", http.StatusServiceUnavailable) +} diff --git a/app/http_handlers/url_create.go b/app/http_handlers/url_create.go index 8a79260..2d2177f 100644 --- a/app/http_handlers/url_create.go +++ b/app/http_handlers/url_create.go @@ -1,18 +1,21 @@ package httpHandlers import ( - "github.com/aykhans/oh-my-url/app/utils" - "github.com/aykhans/oh-my-url/app/config" "html/template" + "log" "net/http" netUrl "net/url" "regexp" + + "github.com/aykhans/oh-my-url/app/config" + "github.com/aykhans/oh-my-url/app/errors" + "github.com/aykhans/oh-my-url/app/utils" ) type CreateData struct { ShortedURL string MainURL string - Error string + Error error } func (hl *HandlerCreate) UrlCreate(w http.ResponseWriter, r *http.Request) { @@ -23,7 +26,8 @@ func (hl *HandlerCreate) UrlCreate(w http.ResponseWriter, r *http.Request) { tmpl, err := template.ParseFiles(utils.GetTemplatePaths("index.html")...) if err != nil { - InternalServerError(w, err) + log.Println(err) + InternalServerError(w, errors.ErrAPITemplateParsing) return } @@ -31,7 +35,8 @@ func (hl *HandlerCreate) UrlCreate(w http.ResponseWriter, r *http.Request) { case http.MethodGet: err = tmpl.Execute(w, nil) if err != nil { - InternalServerError(w, err) + log.Println(err) + InternalServerError(w, errors.ErrAPITemplateParsing) return } case http.MethodPost: @@ -41,23 +46,33 @@ func (hl *HandlerCreate) UrlCreate(w http.ResponseWriter, r *http.Request) { if !isValidUrl { data := CreateData{ MainURL: url, - Error: "Invalid URL", + Error: errors.ErrAPIInvalidURL, } err = tmpl.Execute(w, data) if err != nil { - InternalServerError(w, err) + log.Println(err) + InternalServerError(w, errors.ErrAPITemplateParsing) } return } key, err := hl.DB.CreateURL(url) if err != nil { - InternalServerError(w, err) + data := CreateData{ + MainURL: url, + Error: errors.ErrAPI503, + } + err = tmpl.Execute(w, data) + if err != nil { + log.Println(err) + InternalServerError(w, errors.ErrAPITemplateParsing) + } return } shortedURL, err := netUrl.JoinPath(config.GetForwardDomain(), key) if err != nil { - InternalServerError(w, err) + log.Println(err) + InternalServerError(w, errors.ErrAPITemplateParsing) return } data := CreateData{ @@ -66,7 +81,8 @@ func (hl *HandlerCreate) UrlCreate(w http.ResponseWriter, r *http.Request) { } err = tmpl.Execute(w, data) if err != nil { - InternalServerError(w, err) + log.Println(err) + InternalServerError(w, errors.ErrAPITemplateParsing) return } diff --git a/app/main.go b/app/main.go index 9e64b33..b63c1de 100644 --- a/app/main.go +++ b/app/main.go @@ -1,11 +1,13 @@ package main import ( + "log" + "net/http" + "sync" + "github.com/aykhans/oh-my-url/app/config" "github.com/aykhans/oh-my-url/app/db" "github.com/aykhans/oh-my-url/app/http_handlers" - "net/http" - "sync" ) func main() { @@ -27,11 +29,25 @@ func main() { wg.Add(2) go func() { defer wg.Done() - panic(http.ListenAndServe(":"+appConfig.LISTEN_PORT_CREATE, urlCreateMux)) + for { + err := http.ListenAndServe(":"+appConfig.LISTEN_PORT_CREATE, urlCreateMux) + if err != nil { + log.Println(err) + continue + } + break + } }() go func() { defer wg.Done() - panic(http.ListenAndServe(":"+appConfig.LISTEN_PORT_FORWARD, urlReadMux)) + for { + err := http.ListenAndServe(":"+appConfig.LISTEN_PORT_FORWARD, urlReadMux) + if err != nil { + log.Println(err) + continue + } + break + } }() wg.Wait() } diff --git a/app/templates/index.html b/app/templates/index.html index 2461b7a..66452bc 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -93,7 +93,7 @@

Oh My URL!

{{ if .Error }} - + {{ end }} {{ if .ShortedURL }}