From 6e97d867de8eacbfb239bac411a29a0a960d9b41 Mon Sep 17 00:00:00 2001 From: Gonne Date: Wed, 21 Sep 2022 22:24:08 +0200 Subject: [PATCH] Verbessere Logging und Fehlerbehandlung --- config/config.go | 6 +- controllers/addOfficeHourHandler.go | 28 +++++--- controllers/confirmRequestHandler.go | 17 +++-- controllers/deleteOfficeHourHandler.go | 6 +- controllers/getHandlers.go | 18 +++-- controllers/templates.go | 2 +- controllers/timetable.go | 11 ++- main.go | 12 +++- repositories/course.go | 31 ++++---- repositories/officeHour.go | 97 +++++++++++++++++++++----- repositories/request.go | 28 +++++--- repositories/room.go | 16 +++-- repositories/tutor.go | 18 +++-- sqldb/sqldb.go | 21 +++--- 14 files changed, 223 insertions(+), 88 deletions(-) diff --git a/config/config.go b/config/config.go index 1eba4b1..1a98a5c 100644 --- a/config/config.go +++ b/config/config.go @@ -51,12 +51,14 @@ type Config struct { func ReadConfigFile(filename string, conf *Config) error { configData, err := ioutil.ReadFile(filename) if err != nil { - log.Printf("Error reading config file: %s", err.Error()) + err = fmt.Errorf("Error reading config file: %w", err) + log.Println(err.Error()) return err } err = json.Unmarshal(configData, conf) if err != nil { - log.Printf("Error parsing config file as json: %s", err.Error()) + err = fmt.Errorf("Error parsing config file as json: %w", err) + log.Println(err.Error()) return err } return validateConfig(conf) diff --git a/controllers/addOfficeHourHandler.go b/controllers/addOfficeHourHandler.go index 33322b8..aafdf93 100644 --- a/controllers/addOfficeHourHandler.go +++ b/controllers/addOfficeHourHandler.go @@ -149,12 +149,24 @@ func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Requ id, err := b.officeHourRepo.Add(officeHour) if err != nil { w.WriteHeader(http.StatusInternalServerError) - Templates.ExecuteTemplate(w, "addFailure.html", err) + templateError := Templates.ExecuteTemplate(w, "addFailure.html", err) + if templateError != nil { + log.Printf("Error executing template addFailure.html: %s", templateError.Error()) + } return } - officeHour, _ = b.officeHourRepo.FindById(id) - b.requestRepo.Add(officeHour, models.RequestActivate) - Templates.ExecuteTemplate(w, "addSuccess.html", struct{}{}) + officeHour, err = b.officeHourRepo.FindById(id) + if err != nil { + log.Printf("Error finding new office hour by id %d: %s", id, err.Error()) + } + _, err = b.requestRepo.Add(officeHour, models.RequestActivate) + if err != nil { + log.Printf("Error adding request: %s", err.Error()) + } + templateError := Templates.ExecuteTemplate(w, "addSuccess.html", struct{}{}) + if templateError != nil { + log.Printf("Error executing template addSuccess.html: %s", templateError.Error()) + } } } @@ -165,10 +177,10 @@ func (b *BaseHandler) writeAddOfficeHourMask(w http.ResponseWriter, req *http.Re if len(data.Errors) != 0 { w.WriteHeader(http.StatusBadRequest) } - err := Templates.ExecuteTemplate(w, "addMask.html", data) - if err != nil { - log.Printf("Template addMask.html could not be parsed: %s", err.Error()) - w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", err.Error()))) + templateError := Templates.ExecuteTemplate(w, "addMask.html", data) + if templateError != nil { + log.Printf("Error executing template addMask.html: %s", templateError.Error()) + w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", templateError.Error()))) return } } diff --git a/controllers/confirmRequestHandler.go b/controllers/confirmRequestHandler.go index 09ef51a..5cb0309 100644 --- a/controllers/confirmRequestHandler.go +++ b/controllers/confirmRequestHandler.go @@ -1,6 +1,7 @@ package controllers import ( + "log" "net/http" ) @@ -10,16 +11,24 @@ func (b *BaseHandler) ConfirmRequestHandler(w http.ResponseWriter, req *http.Req if err != nil { w.WriteHeader(http.StatusNotFound) - Templates.ExecuteTemplate(w, "requestNotFound.html", struct{}{}) + templateError := Templates.ExecuteTemplate(w, "requestNotFound.html", struct{}{}) + if templateError != nil { + log.Printf("Error executing template requestNotFound.html: %s", templateError.Error()) + } return } err = b.requestRepo.Execute(request) if err != nil { w.WriteHeader(http.StatusInternalServerError) - Templates.ExecuteTemplate(w, "executeFailure.html", err.Error()) + templateError := Templates.ExecuteTemplate(w, "executeFailure.html", err.Error()) + if templateError != nil { + log.Printf("Error executing template executeFailure.html: %s", templateError.Error()) + } return } - Templates.ExecuteTemplate(w, "executeSuccess.html", struct{}{}) - + templateError := Templates.ExecuteTemplate(w, "executeSuccess.html", struct{}{}) + if templateError != nil { + log.Printf("Error executing template executeSuccess.html: %s", templateError.Error()) + } } diff --git a/controllers/deleteOfficeHourHandler.go b/controllers/deleteOfficeHourHandler.go index c38162e..4a84565 100644 --- a/controllers/deleteOfficeHourHandler.go +++ b/controllers/deleteOfficeHourHandler.go @@ -2,6 +2,7 @@ package controllers import ( + "log" "net/http" "officeHours/models" "strconv" @@ -18,7 +19,10 @@ func (b *BaseHandler) DeleteOfficeHourHandler(w http.ResponseWriter, req *http.R w.WriteHeader(http.StatusBadRequest) } _, err = b.requestRepo.Add(officeHour, models.RequestDelete) - Templates.ExecuteTemplate(w, "deleteSuccess.html", struct{}{}) + templateError := Templates.ExecuteTemplate(w, "deleteSuccess.html", struct{}{}) + if templateError != nil { + log.Printf("Error executing template deleteSuccess.html: %s", templateError.Error()) + } } else { officeHours, _ := b.officeHourRepo.GetAll(true) timetable, slots := b.GetTimetable(officeHours) diff --git a/controllers/getHandlers.go b/controllers/getHandlers.go index ca410f4..7b07793 100644 --- a/controllers/getHandlers.go +++ b/controllers/getHandlers.go @@ -3,6 +3,7 @@ package controllers import ( "fmt" "html/template" + "log" "net/http" "officeHours/models" "strconv" @@ -19,7 +20,10 @@ func (b *BaseHandler) GetByRoomHandler(w http.ResponseWriter, req *http.Request) b.RootHandler(w, req) return } - officeHours, _ := b.officeHourRepo.FindByRoom(room, true) + officeHours, err := b.officeHourRepo.FindByRoom(room, true) + if err != nil { + log.Printf("Error getting office hours for room %s: %s", room.Name, err.Error()) + } timetable, slots := b.GetTimetable(officeHours) b.writeTimetablePage(w, req, b.printTimetable(timetable, slots, false)) } @@ -34,7 +38,10 @@ func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Reques b.RootHandler(w, req) return } - officeHours, _ := b.officeHourRepo.FindByCourse(course, true) + officeHours, err := b.officeHourRepo.FindByCourse(course, true) + if err != nil { + log.Printf("Error getting office hours for course %s: %s", course.Name, err.Error()) + } timetable, slots := b.GetTimetable(officeHours) b.writeTimetablePage(w, req, b.printTimetable(timetable, slots, false)) } @@ -51,9 +58,10 @@ func (b *BaseHandler) writeTimetablePage(w http.ResponseWriter, req *http.Reques SelectedRoom int SelectedCourse int }{courses, rooms, timetable, selectedRoom, selectedCourse} - err := Templates.ExecuteTemplate(w, "index.html", data) - if err != nil { - w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", err.Error()))) + templateError := Templates.ExecuteTemplate(w, "index.html", data) + if templateError != nil { + log.Printf("Error executing template index.html: %s", templateError.Error()) + w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", templateError.Error()))) return } } diff --git a/controllers/templates.go b/controllers/templates.go index c87fd8c..aa3ea28 100644 --- a/controllers/templates.go +++ b/controllers/templates.go @@ -5,7 +5,7 @@ import ( "officeHours/models" ) -var Templates, _ = template.Must(template.ParseFiles( +var Templates, TemplateError = template.Must(template.ParseFiles( "templates/addFailure.html", "templates/addMask.html", "templates/addSuccess.html", diff --git a/controllers/timetable.go b/controllers/timetable.go index a16ba21..a82000e 100644 --- a/controllers/timetable.go +++ b/controllers/timetable.go @@ -5,6 +5,7 @@ import ( "bytes" "fmt" "html/template" + "log" "officeHours/models" ) @@ -84,7 +85,10 @@ func (b *BaseHandler) printTimetable(timetable map[models.Date]map[int]models.Of MinuteGranularity int DeleteIcons bool }{OfficeHour: current, MinuteGranularity: b.config.Date.MinuteGranularity, DeleteIcons: deleteIcons} - Templates.ExecuteTemplate(&celldata, "td.html", data) + templateError := Templates.ExecuteTemplate(&celldata, "td.html", data) + if templateError != nil { + log.Printf("Error executing template td.html: %s", templateError.Error()) + } tableBody += celldata.String() } } else { @@ -116,6 +120,9 @@ func (b *BaseHandler) printTimetable(timetable map[models.Date]map[int]models.Of slots[4], template.HTML(tableBody), } - Templates.ExecuteTemplate(&table, "officeHourTable.html", tableData) + templateError := Templates.ExecuteTemplate(&table, "officeHourTable.html", tableData) + if templateError != nil { + log.Printf("Error executing template officeHourTable.html: %s", templateError.Error()) + } return template.HTML(table.String()) } diff --git a/main.go b/main.go index 1a88bc9..9297b2b 100644 --- a/main.go +++ b/main.go @@ -7,11 +7,11 @@ import ( "log" "log/syslog" "net/http" - "os" "officeHours/config" "officeHours/controllers" "officeHours/repositories" "officeHours/sqldb" + "os" ) func main() { @@ -19,6 +19,11 @@ func main() { if e == nil { log.SetOutput(logwriter) } + + if controllers.TemplateError != nil { + log.Fatalf("Error parsing templates: %s", controllers.TemplateError.Error()) + } + configFile := flag.String( "config", "config/config.json", @@ -35,7 +40,10 @@ func main() { log.Fatalf("%s: %s", "Reading JSON config file into config structure", err) } - db := sqldb.Connect(conf) + db, err := sqldb.Connect(conf) + if err != nil { + log.Fatalf(err.Error()) + } // Create repos roomRepo := repositories.NewRoomRepo(db) courseRepo := repositories.NewCourseRepo(db) diff --git a/repositories/course.go b/repositories/course.go index 68dd801..e721130 100644 --- a/repositories/course.go +++ b/repositories/course.go @@ -3,6 +3,9 @@ package repositories import ( "database/sql" + "errors" + "fmt" + "log" "officeHours/models" ) @@ -17,26 +20,17 @@ func NewCourseRepo(db *sql.DB) *CourseRepo { } func (r *CourseRepo) FindByName(name string) (models.Course, error) { - row := r.db.QueryRow("SELECT * FROM course WHERE name=?", name) - var course models.Course - if err := row.Scan(&course.Id, &course.Name); err != nil { - return models.Course{}, err - } - return course, nil + return r.getFromRow(r.db.QueryRow("SELECT * FROM course WHERE name=?", name)) } func (r *CourseRepo) FindById(id int) (models.Course, error) { - row := r.db.QueryRow("SELECT * FROM course WHERE id=?", id) - var course models.Course - if err := row.Scan(&course.Id, &course.Name); err != nil { - return models.Course{}, err - } - return course, nil + return r.getFromRow(r.db.QueryRow("SELECT * FROM course WHERE id=?", id)) } func (r *CourseRepo) GetAll() ([]models.Course, error) { rows, err := r.db.Query("SELECT * FROM course") if err != nil { + log.Printf("Error getting all courses: %s", err.Error()) return nil, err } defer rows.Close() @@ -49,9 +43,22 @@ func (r *CourseRepo) getFromRows(rows *sql.Rows) ([]models.Course, error) { for rows.Next() { var course models.Course if err := rows.Scan(&course.Id, &course.Name); err != nil { + log.Printf("Error scanning course row: %s", err.Error()) return courses, err } courses = append(courses, course) } return courses, nil } + +func (r *CourseRepo) getFromRow(row *sql.Row) (models.Course, error) { + var course models.Course + if err := row.Scan(&course.Id, &course.Name); err != nil { + err = fmt.Errorf("Error getting course row: %w", err) + if !errors.Is(err, sql.ErrNoRows) { + log.Printf(err.Error()) + } + return models.Course{}, err + } + return course, nil +} diff --git a/repositories/officeHour.go b/repositories/officeHour.go index dae2213..e92093f 100644 --- a/repositories/officeHour.go +++ b/repositories/officeHour.go @@ -3,7 +3,9 @@ package repositories import ( "database/sql" + "errors" "fmt" + "log" "officeHours/config" "officeHours/models" ) @@ -35,7 +37,11 @@ func (r *OfficeHourRepo) GetAll(activeOnly bool) ([]models.OfficeHour, error) { rows, err = r.db.Query("SELECT * FROM officeHour") } if err != nil { - return nil, fmt.Errorf("Error getting all officeHours from database: %s", err.Error()) + err = fmt.Errorf("Error getting all officeHours from database: %w", err) + if !errors.Is(err, sql.ErrNoRows) { + log.Println(err.Error()) + } + return nil, err } defer rows.Close() return r.getFromRows(rows) @@ -49,10 +55,14 @@ func (r *OfficeHourRepo) FindByCourse(course models.Course, activeOnly bool) ([] } else { rows, err = r.db.Query("SELECT * FROM officeHour WHERE course=?", course.Id) } - if err != nil { - return nil, fmt.Errorf("Error getting officeHours by course from database: %s", err.Error()) - } defer rows.Close() + if err != nil { + err = fmt.Errorf("Error getting officeHours by course from database: %w", err) + if !errors.Is(err, sql.ErrNoRows) { + log.Println(err.Error()) + } + return nil, err + } return r.getFromRows(rows) } @@ -65,7 +75,11 @@ func (r *OfficeHourRepo) FindByRoom(room models.Room, activeOnly bool) ([]models rows, err = r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id) } if err != nil { - return nil, fmt.Errorf("Error getting officeHours by room from database: %s", err.Error()) + err = fmt.Errorf("Error getting officeHours by room from database: %w", err) + if !errors.Is(err, sql.ErrNoRows) { + log.Println(err.Error()) + } + return nil, err } defer rows.Close() return r.getFromRows(rows) @@ -75,11 +89,16 @@ func (r *OfficeHourRepo) FindById(id int) (models.OfficeHour, error) { return r.getFromRow(r.db.QueryRow("SELECT * FROM officeHour WHERE id=?", id)) } -func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) (id int, err error) { +func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) (int, error) { // Find correct tutor or add if not existent - r.tutorRepo.Add(officeHour.Tutor) + _, err := r.tutorRepo.Add(officeHour.Tutor) + if err != nil { + return 0, err + } officeHour.Tutor, err = r.tutorRepo.FindByNameAndEmail(officeHour.Tutor.Name, officeHour.Tutor.Email) if err != nil { + err = fmt.Errorf("Newly added tutor not found: %w", err) + log.Println(err.Error()) return 0, err } @@ -111,14 +130,19 @@ func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) (id int, err error) { officeHour.Info, officeHour.Active, officeHour.Duration) - id64, _ := sqlResult.LastInsertId() - return int(id64), err + id, lastInsertIdErr := sqlResult.LastInsertId() + if lastInsertIdErr != nil { + log.Printf("Error getting Id for new tutor: %s", lastInsertIdErr.Error()) + } + return int(id), err } func (r *OfficeHourRepo) Delete(officeHour models.OfficeHour) error { _, err := r.db.Exec("DELETE FROM officeHour WHERE id=?", officeHour.Id) if err != nil { - return fmt.Errorf("Error deleting officeHour from database: %s", err.Error()) + err = fmt.Errorf("Error deleting officeHour from database: %w", err) + log.Println(err.Error()) + return err } return nil } @@ -128,12 +152,29 @@ func (r *OfficeHourRepo) getFromRow(row *sql.Row) (models.OfficeHour, error) { var week, day, hour, minute, tutorId, courseId, roomId int err := row.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &courseId, &week, &officeHour.Info, &officeHour.Active, &officeHour.Duration) if err != nil { - return models.OfficeHour{}, fmt.Errorf("Error getting single officeHours row from database: %s", err.Error()) + err = fmt.Errorf("Error getting single officeHour row from database: %w", err) + log.Println(err.Error()) + return models.OfficeHour{}, err } officeHour.Date = models.Date{Week: week, Day: day, Hour: hour, Minute: minute} - officeHour.Room, _ = r.roomRepo.FindById(roomId) - officeHour.Tutor, _ = r.tutorRepo.FindById(tutorId) - officeHour.Course, _ = r.courseRepo.FindById(courseId) + officeHour.Room, err = r.roomRepo.FindById(roomId) + if err != nil { + err = fmt.Errorf("Error finding room by id %d for office hour: %w", roomId, err) + log.Println(err.Error()) + return officeHour, err + } + officeHour.Tutor, err = r.tutorRepo.FindById(tutorId) + if err != nil { + err = fmt.Errorf("Error finding tutor by id %d for office hour: %w", tutorId, err) + log.Println(err.Error()) + return officeHour, err + } + officeHour.Course, err = r.courseRepo.FindById(courseId) + if err != nil { + err = fmt.Errorf("Error finding course by id %d for office hour: %w", courseId, err) + log.Println(err.Error()) + return officeHour, err + } return officeHour, nil } @@ -142,13 +183,29 @@ func (r *OfficeHourRepo) getFromRows(rows *sql.Rows) ([]models.OfficeHour, error for rows.Next() { var officeHour models.OfficeHour var week, day, hour, minute, tutorId, roomId, courseId int + var err error if err := rows.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &courseId, &week, &officeHour.Info, &officeHour.Active, &officeHour.Duration); err != nil { - return officeHours, fmt.Errorf("Error getting multiple officeHour rows from database: %s", err.Error()) + return officeHours, fmt.Errorf("Error getting multiple officeHour rows from database: %w", err) } officeHour.Date = models.Date{Week: week, Day: day, Hour: hour, Minute: minute} - officeHour.Room, _ = r.roomRepo.FindById(roomId) - officeHour.Tutor, _ = r.tutorRepo.FindById(tutorId) - officeHour.Course, _ = r.courseRepo.FindById(courseId) + officeHour.Room, err = r.roomRepo.FindById(roomId) + if err != nil { + err = fmt.Errorf("Error finding room by id %d for office hour: %w", roomId, err) + log.Println(err.Error()) + return officeHours, err + } + officeHour.Tutor, err = r.tutorRepo.FindById(tutorId) + if err != nil { + err = fmt.Errorf("Error finding tutor by id %d for office hour: %w", tutorId, err) + log.Println(err.Error()) + return officeHours, err + } + officeHour.Course, err = r.courseRepo.FindById(courseId) + if err != nil { + err = fmt.Errorf("Error finding course by id %d for office hour: %w", courseId, err) + log.Println(err.Error()) + return officeHours, err + } officeHours = append(officeHours, officeHour) } return officeHours, nil @@ -163,7 +220,9 @@ func (r *OfficeHourRepo) NumberByTimeSpanAndRoom(date models.Date, duration int, rows, err = r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id) } if err != nil { - return 0, fmt.Errorf("Error getting officeHours by timespan and room from database: %s", err.Error()) + err = fmt.Errorf("Error getting officeHours by timespan and room from database: %w", err) + log.Println(err.Error()) + return 0, err } defer rows.Close() officeHours, err := r.getFromRows(rows) diff --git a/repositories/request.go b/repositories/request.go index 20bd06b..886d9ee 100644 --- a/repositories/request.go +++ b/repositories/request.go @@ -5,6 +5,7 @@ import ( "bytes" "crypto/rand" "database/sql" + "errors" "fmt" "log" "math/big" @@ -53,6 +54,8 @@ func (r *RequestRepo) FindByOfficeHour(officeHour models.OfficeHour) ([]models.R var request models.Request var officeHourId int if err := rows.Scan(&request.Id, &officeHourId, &request.Action, &request.Secret); err != nil { + err = fmt.Errorf("Error scanning request row: %w", err) + log.Println(err.Error()) return requests, err } request.OfficeHour, err = r.officeHourRepo.FindById(officeHourId) @@ -66,7 +69,7 @@ func (r *RequestRepo) FindByOfficeHour(officeHour models.OfficeHour) ([]models.R func (r *RequestRepo) Add(officeHour models.OfficeHour, action int) (int, error) { existents, err := r.FindByOfficeHour(officeHour) - if err != nil && err != sql.ErrNoRows { + if err != nil && !errors.Is(err, sql.ErrNoRows) { return 0, err } /* Resend confirmation mail if identical request exists, @@ -100,10 +103,10 @@ func (r *RequestRepo) Execute(request models.Request) error { _, err = r.db.Exec("UPDATE officeHour SET active=true WHERE id=?", request.OfficeHour.Id) r.db.Exec("DELETE FROM request WHERE officeHour=?", request.OfficeHour.Id) case models.RequestDelete: - r.officeHourRepo.Delete(request.OfficeHour) + err = r.officeHourRepo.Delete(request.OfficeHour) r.db.Exec("DELETE FROM request WHERE officeHour=?", request.OfficeHour.Id) default: - r.db.Exec("DELETE FROM request WHERE id=?", request.Id) + _, err = r.db.Exec("DELETE FROM request WHERE id=?", request.Id) } return err } @@ -112,10 +115,10 @@ func (r *RequestRepo) newSecret() (string, error) { var err error var secret string // find unused secret - for err != sql.ErrNoRows { + for !errors.Is(err, sql.ErrNoRows) { secret = randomString(r.config.Request.SecretLength) _, err = r.FindBySecret(secret) - if err != nil && err != sql.ErrNoRows { + if err != nil && errors.Is(err, sql.ErrNoRows) { return "", err } } @@ -130,7 +133,8 @@ func (r *RequestRepo) sendConfirmationMail(request models.Request) error { }{r.config, request} err := controllers.Templates.ExecuteTemplate(&message, "confirmationMail", data) if err != nil { - log.Printf("Error parsing confirmation Mail: %s", err.Error()) + err = fmt.Errorf("Error parsing confirmation Mail: %w", err) + log.Println(err.Error()) return err } switch r.config.Mailer.Type { @@ -142,7 +146,12 @@ func (r *RequestRepo) sendConfirmationMail(request models.Request) error { if r.config.Mailer.SmtpUseAuth { auth = smtp.PlainAuth(r.config.Mailer.SmtpIdentity, r.config.Mailer.FromAddress, r.config.Mailer.SmtpPassword, r.config.Mailer.SmtpHost) } - return smtp.SendMail(fmt.Sprintf("%s:%d", r.config.Mailer.SmtpHost, r.config.Mailer.SmtpPort), auth, string(r.config.Mailer.FromName), to, message.Bytes()) + err = smtp.SendMail(fmt.Sprintf("%s:%d", r.config.Mailer.SmtpHost, r.config.Mailer.SmtpPort), auth, string(r.config.Mailer.FromName), to, message.Bytes()) + if err != nil { + err = fmt.Errorf("Error sending mail by smtp: %w", err) + log.Println(err.Error()) + } + return err } return nil } @@ -154,7 +163,10 @@ func randomString(n int) string { s := make([]rune, n) for i := range s { - position, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) + position, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) + if err != nil { + log.Printf("Error getting random position in randomString(n int): %s", err.Error()) + } s[i] = letters[position.Int64()] } return string(s) diff --git a/repositories/room.go b/repositories/room.go index 2ad0c69..771eb8c 100644 --- a/repositories/room.go +++ b/repositories/room.go @@ -3,6 +3,9 @@ package repositories import ( "database/sql" + "errors" + "fmt" + "log" "officeHours/models" ) @@ -29,6 +32,10 @@ func (r *RoomRepo) FindById(id int) (models.Room, error) { row := r.db.QueryRow("SELECT * FROM room WHERE id=?", id) var room models.Room if err := row.Scan(&room.Id, &room.Name, &room.MaxOccupy); err != nil { + err = fmt.Errorf("Error scanning row to get room: %w", err) + if !errors.Is(err, sql.ErrNoRows) { + log.Println(err.Error()) + } return models.Room{}, err } return room, nil @@ -37,6 +44,8 @@ func (r *RoomRepo) FindById(id int) (models.Room, error) { func (r *RoomRepo) GetAll() ([]models.Room, error) { rows, err := r.db.Query("SELECT * FROM room") if err != nil { + err = fmt.Errorf("Error getting all rooms: %w", err) + log.Println(err.Error()) return nil, err } defer rows.Close() @@ -45,15 +54,10 @@ func (r *RoomRepo) GetAll() ([]models.Room, error) { for rows.Next() { var room models.Room if err := rows.Scan(&room.Id, &room.Name, &room.MaxOccupy); err != nil { + err = fmt.Errorf("Error scanning row to get room: %w", err) return rooms, err } rooms = append(rooms, room) } return rooms, nil } -func (r *RoomRepo) Save(room models.Room) error { - return nil -} -func (r *RoomRepo) Add(room models.Room) error { - return nil -} diff --git a/repositories/tutor.go b/repositories/tutor.go index c5693c1..3c84819 100644 --- a/repositories/tutor.go +++ b/repositories/tutor.go @@ -3,6 +3,9 @@ package repositories import ( "database/sql" + "errors" + "fmt" + "log" "officeHours/models" ) @@ -27,6 +30,8 @@ func (r *TutorRepo) FindByEmail(email string) ([]models.Tutor, error) { for rows.Next() { var tutor models.Tutor if err := rows.Scan(&tutor.Id, &tutor.Name, &tutor.Email); err != nil { + err = fmt.Errorf("Error scanning tutor row: %w", err) + log.Println(err.Error()) return tutors, err } tutors = append(tutors, tutor) @@ -63,23 +68,24 @@ func (r *TutorRepo) GetAll() ([]models.Tutor, error) { for rows.Next() { var tutor models.Tutor if err := rows.Scan(&tutor.Id, &tutor.Name, &tutor.Email); err != nil { + err = fmt.Errorf("Error scanning tutor row: %w", err) + log.Println(err.Error()) return tutors, err } tutors = append(tutors, tutor) } return tutors, nil } -func (r *TutorRepo) Save(tutor models.Tutor) error { - return nil -} func (r *TutorRepo) Add(tutor models.Tutor) (int, error) { //Don't add identical tutors existentTutor, err := r.FindByNameAndEmail(tutor.Name, tutor.Email) - if err == sql.ErrNoRows { + if errors.Is(err, sql.ErrNoRows) { sqlResult, err := r.db.Exec("INSERT INTO `tutor` (name, email) VALUES (?,?)", tutor.Name, tutor.Email) - id, _ := sqlResult.LastInsertId() + id, lastInsertIdErr := sqlResult.LastInsertId() + if lastInsertIdErr != nil { + log.Printf("Error getting Id for new tutor: %s", lastInsertIdErr.Error()) + } return int(id), err } return existentTutor.Id, err - } diff --git a/sqldb/sqldb.go b/sqldb/sqldb.go index 783ba88..f4c5e26 100644 --- a/sqldb/sqldb.go +++ b/sqldb/sqldb.go @@ -3,14 +3,13 @@ package sqldb import ( "database/sql" "fmt" - "log" "officeHours/config" _ "github.com/go-sql-driver/mysql" _ "github.com/mattn/go-sqlite3" ) -func Connect(config config.Config) *sql.DB { +func Connect(config config.Config) (*sql.DB, error) { switch config.SQL.Type { case "SQLite": return connectSQLite(config.SQL.SQLiteFile) @@ -21,30 +20,28 @@ func Connect(config config.Config) *sql.DB { config.SQL.MysqlPort, config.SQL.MysqlDatabase) default: - log.Fatal("Type of database not recognised.") + return nil, fmt.Errorf("Type of database not recognised: %s", config.SQL.Type) } - return nil } -func connectSQLite(file string) *sql.DB { +func connectSQLite(file string) (*sql.DB, error) { db, err := sql.Open("sqlite3", file) if err != nil { - log.Fatal(err) + return db, fmt.Errorf("Error opening SQLite database: %w", err) } - - return db + return db, nil } -func connectMysql(user string, password string, address string, port int, database string) *sql.DB { +func connectMysql(user string, password string, address string, port int, database string) (*sql.DB, error) { db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", user, password, address, port, database)) if err != nil { - log.Fatalf("Error connecting to database: %s", err) + return db, fmt.Errorf("Error connecting to Mysql database: %w", err) } err = db.Ping() // handle error if err != nil { - log.Fatalf("Error pinging database: %s", err) + return db, fmt.Errorf("Error pinging Mysql database: %w", err) } - return db + return db, nil }