CCCPaste

sqlc error handler

package main

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"gotesting/db"
	"log"
	"net/http"

	"github.com/mattn/go-sqlite3"
)


type query[RES, ID any] func(context.Context, ID) (RES, error)

func RunQuery[RES, ID any](ctx context.Context, query query[RES, ID], id ID) (RES, int, error) {
	res, err :=  query(ctx, id)

	if err != nil {
		switch true {
			case ctx.Err() == context.DeadlineExceeded:
				return res, http.StatusGatewayTimeout, errors.New("query took too long")

			case errors.Is(err, sql.ErrNoRows):
				return res, http.StatusNotFound, errors.New("datas not found")

			case errors.As(err, &sqlite3.Error{ExtendedCode: sqlite3.ErrConstraintUnique}):
				return res, http.StatusBadRequest, errors.New("one or more fields already exists in the database")

			case errors.As(err, &sqlite3.Error{ExtendedCode: sqlite3.ErrConstraintCheck}):
				return res, http.StatusBadRequest, errors.New("one or more fields in the query are invalid")

			default:
				log.Println(err)
				return res, http.StatusInternalServerError, errors.New("database error")
		}
	}

	return res, 0, nil
}


func main() {
	db.InitDB()


	user, status, err := RunQuery(context.Background(), db.Query.GetUser, 67_69_420)

	if err != nil {
		log.Fatal(status, err)
	}

	fmt.Println(user)
}