-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add manual tracing to Identity #5283
Conversation
Update master
Merge upstream
Merge upstream
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good! "Hide whitespace changes" helped ;)
span.setStatus({ | ||
code: CanonicalCode.UNAUTHENTICATED, | ||
message: err.message | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: missing semi-colon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good eyes! Definitely need to get lint working...
return tokenResponse; | ||
return tokenResponse; | ||
} catch (err) { | ||
const code = err instanceof AuthenticationError ? CanonicalCode.UNAUTHENTICATED : CanonicalCode.UNKNOWN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be safer to check the err.name for AuthenticationError
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it's true that errors from another context (e.g. iframe) will fail instanceof checks, but the downside of using name is that if you want inheritance in your Error objects then you can't handle classes of errors together.
E.g. you can imagine doing something like
class ValidationError extends Error {}
class RangeError extends ValidationError {}
try {
// something
} catch (e) {
if (e instanceof ValidationError) {
// this works for RangeError!
}
}
I'm flexible on if we want to move to a name-based pattern (or some other approach), but since Identity was already relying on instanceof AuthenticationError
in other code, I think keeping it consistent is fine for now.
/cc @bterlson if he has any design guidance for us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I talked to Brian. This usage of instanceof probably is safe, but he was generally in favor of moving to checking name since we don't have plans for hierarchical errors anytime soon. I'll look at switching this over.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha. I think we had had some issue when using custom errors in core-amqp that made us switch to doing the name check but I’ll have to double-check to confirm. Didn’t realize it was already being done in the rest of the SDK and generally agree to favor consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved this over to using name checks, please take another look
(err.code === RestError.REQUEST_SEND_ERROR || err.code === RestError.REQUEST_ABORTED_ERROR) | ||
) { | ||
// Either request failed or IMDS endpoint isn't available | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the status of the span be a failure in this case? Unauthenticated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think UNAVAILABLE
makes more sense here, since we're checking the availability of the endpoint. Good spotting that catch
wasn't rethrowing here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great for the most part! The testing approach looks solid. A few other comments below
} catch (err) { | ||
span.setStatus({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of this loop is to try each credential in the chain until one is able to authenticate successfully. If there are 3 credentials in the chain and the first two throw an exception but the last succeeds, shouldn't the span be considered successful? Maybe we should only trace in line 44/53 below where the AggregateAuthenticationError
gets thrown and use the message from that exception instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The span is specific to the work it wraps. I think we do actually want to see that some spans failed, as it's the trace that will ultimately succeed (if there's a top-level span that wraps the chain, that could indicate success or failure as well).
For example, it can be useful for the customer to see that the 1st credential always fails, or only the 1st and 3rd pass. Then they could create their own chain if they wanted. Or maybe they think they are using one credential but it turns out that one is failing and they always fall back to another.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, the span is started outside the loop, not inside. (Missed that context when just reading the comment).
return (tokenResponse && tokenResponse.accessToken) || null; | ||
} catch (err) { | ||
span.setStatus({ | ||
code: CanonicalCode.UNKNOWN, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When should we use UNKNOWN
versus UNAUTHENTICATED
? Seems like a distinction might need to be made on the error type as done elsewhere in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UNKNOWN
is the generic failure; I agree with adding the error type checking here.
return (tokenResponse && tokenResponse.accessToken) || null; | ||
} catch (err) { | ||
span.setStatus({ | ||
code: CanonicalCode.UNKNOWN, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe UNAUTHENTICATED
?
return (tokenResponse && tokenResponse.accessToken) || null; | ||
} catch (err) { | ||
span.setStatus({ | ||
code: CanonicalCode.UNKNOWN, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe UNAUTHENTICATED
?
return (tokenResponse && tokenResponse.accessToken) || null; | ||
} catch (err) { | ||
span.setStatus({ | ||
code: CanonicalCode.UNKNOWN, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe UNAUTHENTICATED
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks a lot!
This PR:
This PR cleans up a previous effort by Sarangan (pull #5019).
Love to get feedback on the feel of the tests, if there is anything folks would like to see done differently.