mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-18 17:05:29 +00:00
scan error formatting (#5628)
This commit is contained in:
parent
2ac9aaf871
commit
87e99be4f6
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/output"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/contextargs"
|
||||
"github.com/projectdiscovery/utils/errkit"
|
||||
)
|
||||
|
||||
type ScanContextOption func(*ScanContext)
|
||||
@ -30,7 +31,7 @@ type ScanContext struct {
|
||||
OnWarning func(string)
|
||||
|
||||
// unexported state fields
|
||||
errors []error
|
||||
error error
|
||||
warnings []string
|
||||
events []*output.InternalWrappedEvent
|
||||
results []*output.ResultEvent
|
||||
@ -52,8 +53,8 @@ func (s *ScanContext) Context() context.Context {
|
||||
return s.ctx
|
||||
}
|
||||
|
||||
func (s *ScanContext) GenerateErrorMessage() string {
|
||||
return joinErrors(s.errors)
|
||||
func (s *ScanContext) GenerateErrorMessage() error {
|
||||
return s.error
|
||||
}
|
||||
|
||||
// GenerateResult returns final results slice from all events
|
||||
@ -94,13 +95,16 @@ func (s *ScanContext) LogError(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if s.OnError != nil {
|
||||
s.OnError(err)
|
||||
}
|
||||
s.errors = append(s.errors, err)
|
||||
if s.error == nil {
|
||||
s.error = err
|
||||
} else {
|
||||
s.error = errkit.Append(s.error, err)
|
||||
}
|
||||
|
||||
errorMessage := s.GenerateErrorMessage()
|
||||
errorMessage := s.GenerateErrorMessage().Error()
|
||||
|
||||
for _, result := range s.results {
|
||||
result.Error = errorMessage
|
||||
@ -129,14 +133,3 @@ func (s *ScanContext) LogWarning(format string, args ...any) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// joinErrors joins multiple errors and returns a single error string
|
||||
func joinErrors(errors []error) string {
|
||||
var errorMessages []string
|
||||
for _, e := range errors {
|
||||
if e != nil {
|
||||
errorMessages = append(errorMessages, e.Error())
|
||||
}
|
||||
}
|
||||
return strings.Join(errorMessages, "; ")
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@ import (
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/tmplexec/flow"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/tmplexec/generic"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/tmplexec/multiproto"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/types/nucleierr"
|
||||
"github.com/projectdiscovery/utils/errkit"
|
||||
)
|
||||
|
||||
@ -207,7 +206,7 @@ func (e *TemplateExecuter) Execute(ctx *scan.ScanContext) (bool, error) {
|
||||
ctx.LogError(errx)
|
||||
|
||||
if lastMatcherEvent != nil {
|
||||
lastMatcherEvent.InternalEvent["error"] = tryParseCause(fmt.Errorf("%s", ctx.GenerateErrorMessage()))
|
||||
lastMatcherEvent.InternalEvent["error"] = getErrorCause(ctx.GenerateErrorMessage())
|
||||
writeFailureCallback(lastMatcherEvent, e.options.Options.MatcherStatus)
|
||||
}
|
||||
|
||||
@ -222,7 +221,7 @@ func (e *TemplateExecuter) Execute(ctx *scan.ScanContext) (bool, error) {
|
||||
Info: e.options.TemplateInfo,
|
||||
Type: e.getTemplateType(),
|
||||
Host: ctx.Input.MetaInput.Input,
|
||||
Error: tryParseCause(fmt.Errorf("%s", ctx.GenerateErrorMessage())),
|
||||
Error: getErrorCause(ctx.GenerateErrorMessage()),
|
||||
},
|
||||
},
|
||||
OperatorsResult: &operators.Result{
|
||||
@ -235,31 +234,27 @@ func (e *TemplateExecuter) Execute(ctx *scan.ScanContext) (bool, error) {
|
||||
return executed.Load() || matched.Load(), errx
|
||||
}
|
||||
|
||||
// tryParseCause tries to parse the cause of given error
|
||||
// getErrorCause tries to parse the cause of given error
|
||||
// this is legacy support due to use of errorutil in existing libraries
|
||||
// but this should not be required once all libraries are updated
|
||||
func tryParseCause(err error) string {
|
||||
errStr := ""
|
||||
errX := errkit.FromError(err)
|
||||
if errX != nil {
|
||||
var errCause error
|
||||
|
||||
if len(errX.Errors()) > 1 {
|
||||
errCause = errX.Errors()[0]
|
||||
func getErrorCause(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
if errCause == nil {
|
||||
errCause = errX
|
||||
errx := errkit.FromError(err)
|
||||
var cause error
|
||||
for _, e := range errx.Errors() {
|
||||
if e != nil && strings.Contains(e.Error(), "context deadline exceeded") {
|
||||
continue
|
||||
}
|
||||
|
||||
msg := strings.Trim(errCause.Error(), "{} ")
|
||||
parts := strings.Split(msg, ":")
|
||||
errCause = errkit.New("%s", parts[len(parts)-1])
|
||||
errKind := errkit.GetErrorKind(err, nucleierr.ErrTemplateLogic).String()
|
||||
errStr = errCause.Error()
|
||||
errStr = strings.TrimSpace(strings.Replace(errStr, "errKind="+errKind, "", -1))
|
||||
cause = e
|
||||
break
|
||||
}
|
||||
|
||||
return errStr
|
||||
if cause == nil {
|
||||
cause = errkit.Append(errkit.New("could not get error cause"), errx)
|
||||
}
|
||||
// parseScanError prettifies the error message and removes everything except the cause
|
||||
return parseScanError(cause.Error())
|
||||
}
|
||||
|
||||
// ExecuteWithResults executes the protocol requests and returns results instead of writing them.
|
||||
|
||||
@ -1,10 +1,15 @@
|
||||
package tmplexec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/scan"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/tmplexec/flow"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/tmplexec/generic"
|
||||
"github.com/projectdiscovery/nuclei/v3/pkg/tmplexec/multiproto"
|
||||
"github.com/projectdiscovery/utils/errkit"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -30,3 +35,37 @@ type TemplateEngine interface {
|
||||
// Name returns name of template engine
|
||||
Name() string
|
||||
}
|
||||
|
||||
var (
|
||||
// A temporary fix to remove errKind from error message
|
||||
// this is because errkit is not used everywhere yet
|
||||
reNoKind = regexp.MustCompile(`([\[][^][]+[\]]|errKind=[^ ]+) `)
|
||||
)
|
||||
|
||||
// parseScanError parses given scan error and only returning the cause
|
||||
// instead of inefficient one
|
||||
func parseScanError(msg string) string {
|
||||
if msg == "" {
|
||||
return ""
|
||||
}
|
||||
if strings.HasPrefix(msg, "ReadStatusLine:") {
|
||||
// last index is actual error (from rawhttp)
|
||||
parts := strings.Split(msg, ":")
|
||||
msg = strings.TrimSpace(parts[len(parts)-1])
|
||||
}
|
||||
if strings.Contains(msg, "read ") {
|
||||
// same here
|
||||
parts := strings.Split(msg, ":")
|
||||
msg = strings.TrimSpace(parts[len(parts)-1])
|
||||
}
|
||||
e := errkit.FromError(errors.New(msg))
|
||||
for _, err := range e.Errors() {
|
||||
if err != nil && strings.Contains(err.Error(), "context deadline exceeded") {
|
||||
continue
|
||||
}
|
||||
msg = reNoKind.ReplaceAllString(err.Error(), "")
|
||||
return msg
|
||||
}
|
||||
wrapped := errkit.Append(errkit.New("failed to get error cause"), e).Error()
|
||||
return reNoKind.ReplaceAllString(wrapped, "")
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user