Skip to content

Some methods for bots to notify a developer about runtime errors

License

Notifications You must be signed in to change notification settings

kaibox-git/report

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Report

The report package contains methods for bots to notify a developer about runtime errors. The notification can be by email and into log file.

Install

go get github.com/kaibox-git/report

Usage

object - any object you want to include to a report with an error. As a rule, it contains some values regarding the current data processing.

// Report error:
report.Error(object, err)
// Report sql error:
report.SqlError(object, err, query, params...)
// Send a message
report.Message(subject, body)
// Print sql query with inlined parameters to stdout (console) while testing
report.Sql(query, params...)

Examples

// init email client: https://github.com/kaibox-git/lmail
host := `localhost`
port := 25
connTimeout := time.Second // for local smtp server
/*
Only 20 emails per 30 minutes. The rest is ignored.
This is useful for notifications of errors, but has a limitation if emailing is too often.
In this case keep logging info to file.
*/
emailNumber := 20 
period := 30 * time.Minute
emailSender, err := smtpclient.New(host, port, connTimeout, emailNumber, period)
if err != nil {
    println(err.Error())
    os.Exit(1)
}

// init simple logger for demonstration purposes
errorLogger := log.New(os.Stdout, "INFO:\t", log.Ldate|log.Ltime)

// init report client
appName := `mybot`
from := mail.Address{`Robot`,`no-reply@domain.com`}
to := []mail.Address{
    {`To me`,`developer@domain.com`},
}

report, err := report.New(appName, emailSender, from, to, errorLogger)
if err != nil {
    println(err.Error())
    os.Exit(1)
}

// Now we are ready to use the report

report.Message(appName + ` started`, ``)

...

url := `https://domain.com`
request, err := http.NewRequest("GET", url, nil)
if err != nil {
    report.Error(url, err) // you can pass 'url' as first parameter to include this value to a report
    return report.ErrInternal
}

...

func (repo *SomeRepo) SelectSomeTable(ctx context.Context, object interface{}, SubjectId int) (uint, error) {
    // Timings (QueryDeadline & QueryTimeWarning):
    queryCtx, cancel := context.WithTimeout(ctx, repo.QueryDeadline) // Cancel query if QueryDeadline is exceeded.
    defer cancel()
    queryStart := time.Now()

    var id uint
    // for postgres:
    query := repo.db.Rebind(`SELECT id FROM some_table WHERE subject_id=? AND actual`)
    params := []interface{}{SubjectId}
    if err := repo.db.QueryRowContext(queryCtx, query, params...).Scan(&id); err != nil {
        switch {
        case errors.Is(queryCtx.Err(), context.Canceled), errors.Is(queryCtx.Err(), context.DeadlineExceeded):
            return 0, uerror.Context
        case err == sql.ErrNoRows:
            return 0, uerror.NotFound
        default:
            // If there is some context data (object) to this query that you want to see in a report you can pass it as first parameter or pass nil.
            repo.report.SqlError(object, err, query, params...) 
            return 0, report.ErrInternal
        }
    }

    // Warning if QueryTimeWarning is exceeded.
    queryTime := time.Since(queryStart)
    if queryTime > repo.QueryTimeWarning {
        repo.report.SqlError(object, fmt.Errorf("query time: %v", queryTime), query, params...)
    }

    return id, nil
}

While testing you can use report.Sql()

subjectId = 5
categoryId = 2
query := `SELECT id FROM some_table WHERE subject_id=? AND category_id=?`
params := []interface{}{subjectId, categoryId}
report.Sql(query, params...)

to print sql query with inlined parameters to stdout (console):

SELECT id FROM some_table WHERE subject_id=5 AND category_id=2

Now you can execute this query in the database console.

About

Some methods for bots to notify a developer about runtime errors

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages