remove internal package and hardcoded translations

This commit is contained in:
Pavel 2019-09-04 15:52:41 +03:00
parent 34cba277b9
commit 562f1b1c0b
6 changed files with 121 additions and 141 deletions

View File

@ -3,11 +3,23 @@ package core
import ( import (
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"regexp"
"github.com/op/go-logging" "github.com/op/go-logging"
"gopkg.in/yaml.v2" "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 // ConfigInterface settings data structure
type ConfigInterface interface { type ConfigInterface interface {
GetVersion() string GetVersion() string

View File

@ -1,14 +1,15 @@
package core package core
import ( import (
"errors"
"fmt" "fmt"
"net/http" "net/http"
"reflect" "reflect"
"runtime"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"github.com/Neur0toxine/mg-transport-lib/internal" "github.com/pkg/errors"
"github.com/getsentry/raven-go" "github.com/getsentry/raven-go"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/op/go-logging" "github.com/op/go-logging"
@ -227,7 +228,7 @@ func (s *Sentry) ErrorCaptureHandler() ErrorHandlerFunc {
for _, err := range c.Errors { for _, err := range c.Errors {
if s.Stacktrace { if s.Stacktrace {
stacktrace := internal.NewRavenStackTrace(s.Client, err.Err, 0) stacktrace := newRavenStackTrace(s.Client, err.Err, 0)
go s.Client.CaptureMessageAndWait( go s.Client.CaptureMessageAndWait(
err.Error(), err.Error(),
tags, tags,
@ -380,3 +381,100 @@ func (t *SentryTaggedScalar) BuildTags(v interface{}) (items map[string]string,
} }
return 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" "sync/atomic"
"time" "time"
"github.com/Neur0toxine/mg-transport-lib/internal"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/aws/session"
@ -40,7 +39,7 @@ func NewUtils(awsConfig ConfigAWS, localizer *Localizer, logger *logging.Logger,
Localizer: localizer, Localizer: localizer,
Logger: logger, Logger: logger,
TokenCounter: 0, 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.TokenCounter = tokenCounter
u.ConfigAWS = awsConfig u.ConfigAWS = awsConfig
u.IsDebug = debug u.IsDebug = debug
u.slashRegex = internal.SlashRegex u.slashRegex = slashRegex
} }
// GenerateToken will generate long pseudo-random string. // 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 { if !cr.Success {
u.Logger.Error(url, status, e.ApiErr, cr) 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 { if res := u.checkCredentials(cr.Credentials); len(res) != 0 {
u.Logger.Error(url, status, res) u.Logger.Error(url, status, res)
return nil, return nil, http.StatusBadRequest, errors.New("missing credentials")
http.StatusBadRequest,
errors.New(
u.Localizer.GetLocalizedTemplateMessage(
"missing_credentials",
map[string]interface{}{
"Credentials": strings.Join(res, ", "),
},
),
)
} }
return client, 0, nil return client, 0, nil
} }
func (u *Utils) checkCredentials(credential []string) []string { func (u *Utils) checkCredentials(credential []string) []string {
rc := make([]string, len(internal.CredentialsTransport)) rc := make([]string, len(credentialsTransport))
copy(rc, internal.CredentialsTransport) copy(rc, credentialsTransport)
for _, vc := range credential { for _, vc := range credential {
for kn, vn := range rc { for kn, vn := range rc {
@ -188,7 +178,7 @@ func GetEntitySHA1(v interface{}) (hash string, err error) {
// ReplaceMarkdownSymbols will remove markdown symbols from text // ReplaceMarkdownSymbols will remove markdown symbols from text
func ReplaceMarkdownSymbols(s string) string { func ReplaceMarkdownSymbols(s string) string {
for _, v := range internal.MarkdownSymbols { for _, v := range markdownSymbols {
s = strings.Replace(s, v, "\\"+v, -1) s = strings.Replace(s, v, "\\"+v, -1)
} }

View File

@ -4,7 +4,6 @@ import (
"reflect" "reflect"
"github.com/gin-gonic/gin/binding" "github.com/gin-gonic/gin/binding"
"github.com/Neur0toxine/mg-transport-lib/internal"
"gopkg.in/go-playground/validator.v8" "gopkg.in/go-playground/validator.v8"
) )
@ -20,5 +19,5 @@ func validateCrmURL(
v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value, v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
) bool { ) 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(`/+$`)
)