Files
clr-installer/errors/errors.go
Karthik Prabhu Vinod ccc97c99fa Implement GO Modules
Signed-off-by: Karthik Prabhu Vinod <karthik.prabhu.vinod@intel.com>
2020-02-26 00:51:57 +00:00

107 lines
2.6 KiB
Go

// Copyright © 2018 Intel Corporation
//
// SPDX-License-Identifier: GPL-3.0-only
package errors
import (
"fmt"
"path/filepath"
"runtime"
"strings"
"time"
)
// TraceableError is an internal error used to carry trace details
// to be shared across the multiple layers and reporting facilities
type TraceableError struct {
Trace string
When time.Time
What string
}
// ValidationError is a type of error used to report model or any general condition
// validation error. We don't deal this error as a regular error i.e panic`ing, showing
// the error stack trace and exiting with a non zero code, otherwise, we do show
// a nicely formatted and user friendly error message (the What attribute) and keep
// returning a non zero exit code.
// Consider this error as a user error, not an internal malfunctioning.
type ValidationError struct {
When time.Time
What string
}
func getTraceIdx(idx int) (string, string, int) {
pc := make([]uintptr, 10)
runtime.Callers(2, pc)
f := runtime.FuncForPC(pc[idx+1])
file, line := f.FileLine(pc[idx+1])
return f.Name(), file, line
}
func formatTraceIdx(idx int) (string, string) {
funcName, file, line := getTraceIdx(idx)
fileName := filepath.Base(file)
fn := strings.Split(funcName, "github.com/clearlinux/clr-installer/")
if len(fn) > 1 {
funcName = fn[1]
} else {
funcName = fn[0]
}
dir := filepath.Dir(file)
return funcName, fmt.Sprintf("%s/%s:%d", dir, fileName, line)
}
func getTrace() string {
cfName, cTrace := formatTraceIdx(3)
caller := fmt.Sprintf("%s()\n %s\n", cfName, cTrace)
rfName, rTrace := formatTraceIdx(2)
raiser := fmt.Sprintf("%s()\n %s\n", rfName, rTrace)
return fmt.Sprintf("\n\nError Trace:\n%s%s", raiser, caller)
}
func (e TraceableError) Error() string {
return fmt.Sprintf("%s%s", e.What, e.Trace)
}
// Errorf Returns a new error with the stack information
func Errorf(format string, a ...interface{}) error {
return TraceableError{
Trace: getTrace(),
When: time.Now(),
What: fmt.Sprintf(format, a...),
}
}
// Wrap returns an error with the caller stack information
// embedded in the original error message
func Wrap(err error) error {
return Errorf(err.Error())
}
func (ve ValidationError) Error() string {
return ve.What
}
// ValidationErrorf formats a new ValidationError
func ValidationErrorf(format string, a ...interface{}) error {
return ValidationError{
What: fmt.Sprintf(format, a...),
}
}
// IsValidationError returns true if err is a ValidationError
// returns false otherwise
func IsValidationError(err error) bool {
if _, ok := err.(ValidationError); ok {
return true
}
return false
}