Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xdto record #13

Closed
Aoi-hosizora opened this issue Jan 25, 2021 · 1 comment
Closed

xdto record #13

Aoi-hosizora opened this issue Jan 25, 2021 · 1 comment

Comments

@Aoi-hosizora
Copy link
Owner

package xdto

import (
	"fmt"
	"github.com/Aoi-hosizora/ahlib-web/internal/xmap"
	"github.com/Aoi-hosizora/ahlib/xcolor"
	"github.com/Aoi-hosizora/ahlib/xruntime"
	"log"
	"os"
	"reflect"
	"time"
)

// ErrorDto is a general error response model.
type ErrorDto struct {
	Time    string   `json:"time"`    // current time
	Type    string   `json:"type"`    // error type
	Detail  string   `json:"detail"`  // error detail message
	Request []string `json:"request"` // request details

	Others map[string]interface{} `json:"others,omitempty"` // other message

	Filename  string   `json:"filename,omitempty"`   // stack filename
	Funcname  string   `json:"funcname,omitempty"`   // stack function name
	LineIndex int      `json:"line_index,omitempty"` // file line index
	Line      string   `json:"line,omitempty"`       // stack current line
	Stacks    []string `json:"stacks,omitempty"`     // stacks in skip
}

// BuildBasicErrorDto builds a basic dto (only include time, type, detail, request).
func BuildBasicErrorDto(err interface{}, requests []string, otherKvs ...interface{}) *ErrorDto {
	skip := -2
	return BuildErrorDto(err, requests, skip, false, otherKvs...)
}

// BuildErrorDto builds a complete dto (also include runtime parameters).
func BuildErrorDto(err interface{}, requests []string, skip int, doPrint bool, otherKvs ...interface{}) *ErrorDto {
	if err == nil {
		return nil
	}

	// basic
	now := time.Now().Format(time.RFC3339)
	errType := reflect.TypeOf(err).String()
	errDetail := ""
	if e, ok := err.(error); ok {
		errDetail = e.Error()
	} else {
		errDetail = fmt.Sprintf("%v", err)
	}
	if requests == nil {
		requests = []string{}
	}
	dto := &ErrorDto{Time: now, Type: errType, Detail: errDetail, Request: requests}

	// other
	dto.Others = xmap.SliceToStringMap(otherKvs)

	// runtime
	if skip >= 0 {
		skip++
		var stacks xruntime.TraceStack
		stacks, dto.Filename, dto.Funcname, dto.LineIndex, dto.Line = xruntime.RuntimeTraceStackWithInfo(skip)
		dto.Stacks = make([]string, len(stacks))
		for idx, stack := range stacks {
			dto.Stacks[idx] = stack.String()
		}
		if doPrint {
			l := log.New(os.Stderr, "", 0)
			l.Println()
			l.Println(xcolor.Red.Sprint(stacks.String()))
			l.Println()
		}
	}

	return dto
}
@Aoi-hosizora
Copy link
Owner Author

type RuntimeDto struct {
	Filename   string   `json:"filename,omitempty"`
	Funcname   string   `json:"funcname,omitempty"`
	LineIndex  int      `json:"line_index,omitempty"`
	Line       string   `json:"line,omitempty"`
	TraceStack []string `json:"trace_stack,omitempty"`
}

func BuildRuntimeDto(skip int) *RuntimeDto {
	skip++
	dto, _ := BuildRuntimeDtoWithStack(skip)
	return dto
}

func BuildRuntimeDtoWithStack(skip int) (*RuntimeDto, xruntime.TraceStack) {
	skip++
	stack, filename, funcname, lineIndex, lineText := xruntime.RuntimeTraceStackWithInfo(skip)
	frames := make([]string, len(stack))
	for idx, frame := range stack {
		frames[idx] = frame.String()
	}

	return &RuntimeDto{
		Filename: filename, Funcname: funcname, LineIndex: lineIndex, Line: lineText,
		TraceStack: frames,
	}, stack
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant