Merge pull request #1 from Neur0toxine/master

[improvement] fixes for several non-severe mistakes
This commit is contained in:
Alex Lushpai 2019-09-06 15:32:44 +03:00 committed by GitHub
commit 868a927690
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 142 deletions

View File

@ -1,3 +1,3 @@
## MG Transport Library
This library provides different functions like error-reporting, loggingm localization, etc. in order to make it easier to create transports
This library provides different functions like error-reporting, logging, localization, etc. in order to make it easier to create transports

View File

@ -3,11 +3,23 @@ package core
import (
"io/ioutil"
"path/filepath"
"regexp"
"github.com/op/go-logging"
"gopkg.in/yaml.v2"
)
var (
credentialsTransport = []string{
"/api/integration-modules/{code}",
"/api/integration-modules/{code}/edit",
}
markdownSymbols = []string{"*", "_", "`", "["}
regCommandName = regexp.MustCompile(`^https://?[\da-z.-]+\.(retailcrm\.(ru|pro|es)|ecomlogic\.com|simlachat\.(com|ru))/?$`)
slashRegex = regexp.MustCompile(`/+$`)
)
// ConfigInterface settings data structure
type ConfigInterface interface {
GetVersion() string

View File

@ -1,14 +1,15 @@
package core
import (
"errors"
"fmt"
"net/http"
"reflect"
"runtime"
"runtime/debug"
"strconv"
"github.com/Neur0toxine/mg-transport-lib/internal"
"github.com/pkg/errors"
"github.com/getsentry/raven-go"
"github.com/gin-gonic/gin"
"github.com/op/go-logging"
@ -227,7 +228,7 @@ func (s *Sentry) ErrorCaptureHandler() ErrorHandlerFunc {
for _, err := range c.Errors {
if s.Stacktrace {
stacktrace := internal.NewRavenStackTrace(s.Client, err.Err, 0)
stacktrace := newRavenStackTrace(s.Client, err.Err, 0)
go s.Client.CaptureMessageAndWait(
err.Error(),
tags,
@ -380,3 +381,100 @@ func (t *SentryTaggedScalar) BuildTags(v interface{}) (items map[string]string,
}
return
}
// newRavenStackTrace generate stacktrace compatible with raven-go format
// It tries to extract better stacktrace from error from package "github.com/pkg/errors"
// In case of fail it will fallback to default stacktrace generation from raven-go.
// Default stacktrace highly likely will be useless, because it will not include call
// which returned error. This occurs because default stacktrace doesn't include any call
// before stacktrace generation, and raven-go will generate stacktrace here, which will end
// in trace to this file. But errors from "github.com/pkg/errors" will generate stacktrace
// immediately, it will include call which returned error, and we can fetch this trace.
// Also we can wrap default errors with error from this package, like this:
// errors.Wrap(err, err.Error)
func newRavenStackTrace(client *raven.Client, myerr error, skip int) *raven.Stacktrace {
st := getErrorStackTraceConverted(myerr, 3, client.IncludePaths())
if st == nil {
st = raven.NewStacktrace(skip, 3, client.IncludePaths())
}
return st
}
// getErrorStackTraceConverted will return converted stacktrace from custom error, or nil in case of default error
func getErrorStackTraceConverted(err error, context int, appPackagePrefixes []string) *raven.Stacktrace {
st := getErrorCauseStackTrace(err)
if st == nil {
return nil
}
return convertStackTrace(st, context, appPackagePrefixes)
}
// getErrorCauseStackTrace tries to extract stacktrace from custom error, returns nil in case of failure
func getErrorCauseStackTrace(err error) errors.StackTrace {
// This code is inspired by github.com/pkg/errors.Cause().
var st errors.StackTrace
for err != nil {
s := getErrorStackTrace(err)
if s != nil {
st = s
}
err = getErrorCause(err)
}
return st
}
// convertStackTrace converts github.com/pkg/errors.StackTrace to github.com/getsentry/raven-go.Stacktrace
func convertStackTrace(st errors.StackTrace, context int, appPackagePrefixes []string) *raven.Stacktrace {
// This code is borrowed from github.com/getsentry/raven-go.NewStacktrace().
var frames []*raven.StacktraceFrame
for _, f := range st {
frame := convertFrame(f, context, appPackagePrefixes)
if frame != nil {
frames = append(frames, frame)
}
}
if len(frames) == 0 {
return nil
}
for i, j := 0, len(frames)-1; i < j; i, j = i+1, j-1 {
frames[i], frames[j] = frames[j], frames[i]
}
return &raven.Stacktrace{Frames: frames}
}
// convertFrame converts single frame from github.com/pkg/errors.Frame to github.com/pkg/errors.Frame
func convertFrame(f errors.Frame, context int, appPackagePrefixes []string) *raven.StacktraceFrame {
// This code is borrowed from github.com/pkg/errors.Frame.
pc := uintptr(f) - 1
fn := runtime.FuncForPC(pc)
var file string
var line int
if fn != nil {
file, line = fn.FileLine(pc)
} else {
file = "unknown"
}
return raven.NewStacktraceFrame(pc, file, line, context, appPackagePrefixes)
}
// getErrorStackTrace will try to extract stacktrace from error using StackTrace method (default errors doesn't have it)
func getErrorStackTrace(err error) errors.StackTrace {
ster, ok := err.(interface {
StackTrace() errors.StackTrace
})
if !ok {
return nil
}
return ster.StackTrace()
}
// getErrorCause will try to extract original error from wrapper - it is used only if stacktrace is not present
func getErrorCause(err error) error {
cer, ok := err.(interface {
Cause() error
})
if !ok {
return nil
}
return cer.Cause()
}

View File

@ -12,7 +12,6 @@ import (
"sync/atomic"
"time"
"github.com/Neur0toxine/mg-transport-lib/internal"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
@ -40,7 +39,7 @@ func NewUtils(awsConfig ConfigAWS, localizer *Localizer, logger *logging.Logger,
Localizer: localizer,
Logger: logger,
TokenCounter: 0,
slashRegex: internal.SlashRegex,
slashRegex: slashRegex,
}
}
@ -49,7 +48,7 @@ func (u *Utils) resetUtils(awsConfig ConfigAWS, debug bool, tokenCounter uint32)
u.TokenCounter = tokenCounter
u.ConfigAWS = awsConfig
u.IsDebug = debug
u.slashRegex = internal.SlashRegex
u.slashRegex = slashRegex
}
// GenerateToken will generate long pseudo-random string.
@ -73,29 +72,20 @@ func (u *Utils) GetAPIClient(url, key string) (*v5.Client, int, error) {
if !cr.Success {
u.Logger.Error(url, status, e.ApiErr, cr)
return nil, http.StatusBadRequest, errors.New(u.Localizer.GetLocalizedMessage("incorrect_url_key"))
return nil, http.StatusBadRequest, errors.New("invalid credentials")
}
if res := u.checkCredentials(cr.Credentials); len(res) != 0 {
u.Logger.Error(url, status, res)
return nil,
http.StatusBadRequest,
errors.New(
u.Localizer.GetLocalizedTemplateMessage(
"missing_credentials",
map[string]interface{}{
"Credentials": strings.Join(res, ", "),
},
),
)
return nil, http.StatusBadRequest, errors.New("missing credentials")
}
return client, 0, nil
}
func (u *Utils) checkCredentials(credential []string) []string {
rc := make([]string, len(internal.CredentialsTransport))
copy(rc, internal.CredentialsTransport)
rc := make([]string, len(credentialsTransport))
copy(rc, credentialsTransport)
for _, vc := range credential {
for kn, vn := range rc {
@ -188,7 +178,7 @@ func GetEntitySHA1(v interface{}) (hash string, err error) {
// ReplaceMarkdownSymbols will remove markdown symbols from text
func ReplaceMarkdownSymbols(s string) string {
for _, v := range internal.MarkdownSymbols {
for _, v := range markdownSymbols {
s = strings.Replace(s, v, "\\"+v, -1)
}

View File

@ -4,7 +4,6 @@ import (
"reflect"
"github.com/gin-gonic/gin/binding"
"github.com/Neur0toxine/mg-transport-lib/internal"
"gopkg.in/go-playground/validator.v8"
)
@ -20,5 +19,5 @@ func validateCrmURL(
v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
) bool {
return internal.RegCommandName.Match([]byte(field.Interface().(string)))
return regCommandName.Match([]byte(field.Interface().(string)))
}

View File

@ -1,105 +0,0 @@
package internal
import (
"runtime"
"github.com/getsentry/raven-go"
"github.com/pkg/errors"
)
// NewRavenStackTrace generate stacktrace compatible with raven-go format
// It tries to extract better stacktrace from error from package "github.com/pkg/errors"
// In case of fail it will fallback to default stacktrace generation from raven-go.
// Default stacktrace highly likely will be useless, because it will not include call
// which returned error. This occurs because default stacktrace doesn't include any call
// before stacktrace generation, and raven-go will generate stacktrace here, which will end
// in trace to this file. But errors from "github.com/pkg/errors" will generate stacktrace
// immediately, it will include call which returned error, and we can fetch this trace.
// Also we can wrap default errors with error from this package, like this:
// errors.Wrap(err, err.Error)
func NewRavenStackTrace(client *raven.Client, myerr error, skip int) *raven.Stacktrace {
st := getErrorStackTraceConverted(myerr, 3, client.IncludePaths())
if st == nil {
st = raven.NewStacktrace(skip, 3, client.IncludePaths())
}
return st
}
// getErrorStackTraceConverted will return converted stacktrace from custom error, or nil in case of default error
func getErrorStackTraceConverted(err error, context int, appPackagePrefixes []string) *raven.Stacktrace {
st := getErrorCauseStackTrace(err)
if st == nil {
return nil
}
return convertStackTrace(st, context, appPackagePrefixes)
}
// getErrorCauseStackTrace tries to extract stacktrace from custom error, returns nil in case of failure
func getErrorCauseStackTrace(err error) errors.StackTrace {
// This code is inspired by github.com/pkg/errors.Cause().
var st errors.StackTrace
for err != nil {
s := getErrorStackTrace(err)
if s != nil {
st = s
}
err = getErrorCause(err)
}
return st
}
// convertStackTrace converts github.com/pkg/errors.StackTrace to github.com/getsentry/raven-go.Stacktrace
func convertStackTrace(st errors.StackTrace, context int, appPackagePrefixes []string) *raven.Stacktrace {
// This code is borrowed from github.com/getsentry/raven-go.NewStacktrace().
var frames []*raven.StacktraceFrame
for _, f := range st {
frame := convertFrame(f, context, appPackagePrefixes)
if frame != nil {
frames = append(frames, frame)
}
}
if len(frames) == 0 {
return nil
}
for i, j := 0, len(frames)-1; i < j; i, j = i+1, j-1 {
frames[i], frames[j] = frames[j], frames[i]
}
return &raven.Stacktrace{Frames: frames}
}
// convertFrame converts single frame from github.com/pkg/errors.Frame to github.com/pkg/errors.Frame
func convertFrame(f errors.Frame, context int, appPackagePrefixes []string) *raven.StacktraceFrame {
// This code is borrowed from github.com/pkg/errors.Frame.
pc := uintptr(f) - 1
fn := runtime.FuncForPC(pc)
var file string
var line int
if fn != nil {
file, line = fn.FileLine(pc)
} else {
file = "unknown"
}
return raven.NewStacktraceFrame(pc, file, line, context, appPackagePrefixes)
}
// getErrorStackTrace will try to extract stacktrace from error using StackTrace method (default errors doesn't have it)
func getErrorStackTrace(err error) errors.StackTrace {
ster, ok := err.(interface {
StackTrace() errors.StackTrace
})
if !ok {
return nil
}
return ster.StackTrace()
}
// getErrorCause will try to extract original error from wrapper - it is used only if stacktrace is not present
func getErrorCause(err error) error {
cer, ok := err.(interface {
Cause() error
})
if !ok {
return nil
}
return cer.Cause()
}

View File

@ -1,14 +0,0 @@
package internal
import "regexp"
// CredentialsTransport set of API methods for transport registration
var (
CredentialsTransport = []string{
"/api/integration-modules/{code}",
"/api/integration-modules/{code}/edit",
}
MarkdownSymbols = []string{"*", "_", "`", "["}
RegCommandName = regexp.MustCompile(`^https://?[\da-z.-]+\.(retailcrm\.(ru|pro|es)|ecomlogic\.com|simlachat\.(com|ru))/?$`)
SlashRegex = regexp.MustCompile(`/+$`)
)