Skip to content

fix(errkit): classify errkit errors that have no kind - #829

Open
dwisiswant0 wants to merge 1 commit into
dwisiswant0/fix/errkit/return-errkindunknown-from-kind-without-storing-itfrom
dwisiswant0/fix/errkit/classify-errkit-errors-that-have-no-kind
Open

dwisiswant0 wants to merge 1 commit into
dwisiswant0/fix/errkit/return-errkindunknown-from-kind-without-storing-itfrom
dwisiswant0/fix/errkit/classify-errkit-errors-that-have-no-kind

Conversation

@dwisiswant0

Copy link
Copy Markdown
Member

IsKind and GetErrorKind classify an error from its cause only when
the parsed error has no kind, which they check as a nil kind. But
parseError merged a wrapped *ErrorX's kind unconditionally, and
CombineErrKinds returns an empty, non-nil kind when neither error has
one. So an errkit error, or an error wrapping one, always looked
classified: IsKind returned false for a "no such host" error built
with errkit.New or errkit.Wrap, and GetErrorKind returned an empty
kind instead of falling back to ErrKindUnknown. Only Kind() treated an
empty kind as no kind.

Define that rule once in hasKind and have parseError never store an
empty kind, so a parsed error keeps a nil kind when there is none.
Kind() uses the same rule, and MarshalJSON reports Kind() instead of
repeating its fallback.

errkit errors without a kind now classify the way plain errors with
the same cause do. Callers that branch on the kind see the
difference: retryablehttp-go stops retrying a request whose errkit
error has a permanent network cause, and nuclei's host error cache
skips the host as permanently unresponsive. For errors that match no
kind, GetErrorKind and MarshalJSON report unknown-error instead of
"", so nuclei's error log shows unknown-error for them again (#826),
and ToSlogAttrs leaves the kind out, as it does for plain errors.

Fixes: #827

IsKind and GetErrorKind classify an error from its cause only when
the parsed error has no kind, which they check as a nil kind. But
parseError merged a wrapped *ErrorX's kind unconditionally, and
CombineErrKinds returns an empty, non-nil kind when neither error has
one. So an errkit error, or an error wrapping one, always looked
classified: IsKind returned false for a "no such host" error built
with errkit.New or errkit.Wrap, and GetErrorKind returned an empty
kind instead of falling back to ErrKindUnknown. Only Kind() treated an
empty kind as no kind.

Define that rule once in hasKind and have parseError never store an
empty kind, so a parsed error keeps a nil kind when there is none.
Kind() uses the same rule, and MarshalJSON reports Kind() instead of
repeating its fallback.

errkit errors without a kind now classify the way plain errors with
the same cause do. Callers that branch on the kind see the
difference: retryablehttp-go stops retrying a request whose errkit
error has a permanent network cause, and nuclei's host error cache
skips the host as permanently unresponsive. For errors that match no
kind, GetErrorKind and MarshalJSON report unknown-error instead of
"", so nuclei's error log shows unknown-error for them again (#826),
and ToSlogAttrs leaves the kind out, as it does for plain errors.

Fixes: #827
Signed-off-by: Dwi Siswanto <git@dw1.io>
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

Successfully merging this pull request may close these issues.

errkit: IsKind and GetErrorKind don't detect kinds for errkit errors

1 participant