mirror of
https://github.com/retailcrm/mg-transport-core.git
synced 2024-11-21 20:56:04 +03:00
Merge pull request #1 from Neur0toxine/master
[improvement] fixes for several non-severe mistakes
This commit is contained in:
commit
868a927690
@ -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
|
||||
|
@ -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
|
||||
|
104
core/sentry.go
104
core/sentry.go
@ -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()
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)))
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
@ -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(`/+$`)
|
||||
)
|
Loading…
Reference in New Issue
Block a user