-
Notifications
You must be signed in to change notification settings - Fork 595
fix(bug): Handle errors in response body with status code is 200 #3161
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Melonps <[email protected]>
Signed-off-by: Melonps <[email protected]>
How to use the Graphite Merge QueueAdd the label merge-queue to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. |
Signed-off-by: Melonps <[email protected]>
packages/jaeger-ui/src/api/jaeger.js
Outdated
| if (response.status < 400) { | ||
| return response.json(); | ||
| return response.json().then(body => { | ||
| if (body && Array.isArray(body.errors) && body.errors.length > 0) { |
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.
A function called getJSON cannot assume to know the structure of the response. Why do we need to throw exception in this lower level function instead of handling the error where needed?
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.
Thanks for your feedback🙏
I've refactored the code to keep getJSON generic, and moved the Jaeger specific error handling (where 200 responses can contain an errors array) into the searchTraces method itself.
Without this check, these errors would be silently ignored and treated as successful 200 responses.
…etJSON` Signed-off-by: Melonps <[email protected]>
packages/jaeger-ui/src/api/jaeger.js
Outdated
| error.httpBody = JSON.stringify(body, null, 2); | ||
| throw error; | ||
| } | ||
| return body; |
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.
A successful result is not mutually exclusive with some errors being present. This logic is incorrect. The errors need to be checked by the caller.
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.
@yurishkuro
Thanks for the review ! I understand your point now🙇
I see that fetchMultipleTraces already handles this pattern correctly in packages/jaeger-ui/src/reducers/trace.js, where it processes both payload.data and payload.errors separately. I should follow the same approach for searchTraces, right?
I'll need a bit more time to fix it. Will update the PR soon.
|
I misidentified the root cause. The actual problem is a trace ID normalization mismatch:
I think we should normalize trace IDs to 32-char hex strings on the frontend before issuing API requests by 0, since the Jaeger backend zero-pads them and we need the request and response IDs to align.
|
|
Where does the frontend get the short id from in the first place? |
Signed-off-by: Melonps <[email protected]>
| * normalizeTraceId('1') // '0000000000000001' | ||
| * normalizeTraceId('xyz') // '0000000000000abc' | ||
| * normalizeTraceId('abcd1234') // 'abcd1234' |
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 JSDoc examples are incorrect and misleading:
-
Line 15:
normalizeTraceId('xyz')claims to return'0000000000000abc', but 'xyz' contains no valid hex characters. After cleaning (line 25), it becomes an empty string, triggering line 28-29 to return the original 'xyz' unchanged. -
Line 16:
normalizeTraceId('abcd1234')claims to return'abcd1234', but the function pads to 16 characters (line 33), so it should return'00000000abcd1234'.
Fix the documentation:
* @example
* normalizeTraceId('1') // '0000000000000001'
* normalizeTraceId('xyz') // 'xyz' (invalid, returned unchanged)
* normalizeTraceId('abcd1234') // '00000000abcd1234'
* normalizeTraceId('1234567890abcdef1234') // '1234567890abcdef1234'| * normalizeTraceId('1') // '0000000000000001' | |
| * normalizeTraceId('xyz') // '0000000000000abc' | |
| * normalizeTraceId('abcd1234') // 'abcd1234' | |
| * normalizeTraceId('1') // '0000000000000001' | |
| * normalizeTraceId('xyz') // 'xyz' (invalid, returned unchanged) | |
| * normalizeTraceId('abcd1234') // '00000000abcd1234' | |
| * normalizeTraceId('1234567890abcdef1234') // '1234567890abcdef1234' | |
Spotted by Graphite Agent
Is this helpful? React 👍 or 👎 to let us know.
| return <Search addonBefore="Select by Trace ID" enterButton onSearch={selectTrace} />; | ||
| const handleSearch = React.useCallback( | ||
| (value: string) => { | ||
| selectTrace(normalizeTraceId(value)); |
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.
Are you normalizing raw user input?
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.
@yurishkuro
yes,
Where does the frontend get the short id from in the first place?
Agree that, but I am specifically targeting the scenario where a user manually inputs a Trace ID into the search bar
Sometimes users might input a short ID (e.g., due to a copy paste error or typing only a part of it). Currently, sending this short ID to the backend causes a mismatch with the IDL, leading to an unhandled error that results in the infinite loading state. (UI should show Trace not found.
I agree that we shouldn't handle short IDs internally, but to fix this UX issue (the infinite spinner), I propose applying zero-padding specifically for the search bar input. This ensures the ID format matches what the backend expects (16 or 32 characters) and prevents the UI from hanging.
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.
Actually, It is likely that user input 31-char trace ID in input, because added 0 to tracd Id's head from backend response (ref: # #3079)
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.
if a user inputs invalid ID we should display an error. That the UI keeps spinning in this case is a bug that we need to fix. But we do not need to fix invalid IDs. How do you know their copy&paste omitted the leading zero and not a trailing character?
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.
That makes sense.
I will rework the change to implement client-side validation on the input form. If the user enters a Trace ID with an invalid length, an error will be shown immediately, which will effectively resolve the spinning UI bug while maintaining data integrity.
I'm still learning the ropes, so I really appreciate your feedback. I'll push the fixes shortly.
Signed-off-by: Melonps <[email protected]>
Signed-off-by: Melonps <[email protected]>
Signed-off-by: Melonps <[email protected]>
Signed-off-by: Melonps <[email protected]>
Signed-off-by: Melonps <[email protected]>
|
@yurishkuro |
|
|
||
| import { ValidateError } from '../types/validate-error'; | ||
|
|
||
| export function validateTraceId(traceId: string): ValidateError | null { |
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 UI has no direct dependency on the trace ID being in any specific format. It's just an opaque string for the UI, it should not be adding any additional semantics to that string.
| ids => ({ ids }) | ||
| ); | ||
|
|
||
| export const setTraceValidationError = createAction( |
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.
why does this need to be at the API level instead of just handled in TraceDiff?
| traces[id] = { error, id, state: fetchedState.ERROR }; | ||
| }); | ||
| return { ...state, traces }; | ||
| } |
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.
there is no packages/jaeger-ui/src/reducers/trace.js file in main branch. You fork might be stale.




Which problem is this PR solving?
Description of the changes
In
packages/jaeger-ui/src/api/jaeger.jserrorsarray even when status is 200After this change, I checked to show valid error message in UI, also prevents infinity loading.
Please see the screenshot below:
How was this change tested?
packages/jaeger-ui/src/api/jaeger.test.jsChecklist
jaeger:make lint testjaeger-ui:npm run lintandnpm run test