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
Bug 1839080: fix empty Content in coFetchText causes PipelineLogs to show error #5539
Bug 1839080: fix empty Content in coFetchText causes PipelineLogs to show error #5539
Conversation
@karthikjeeyar: This pull request references Bugzilla bug 1839080, which is valid. The bug has been moved to the POST state. The bug has been updated to refer to the pull request using the external bug tracker. 3 validation(s) were run on this bug
In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/kind bug |
@@ -35,7 +35,8 @@ const Logs: React.FC<LogsProps> = ({ | |||
const appendMessage = React.useRef<(blockContent) => void>(); | |||
appendMessage.current = React.useCallback( | |||
(blockContent) => { | |||
const contentLines = blockContent.split('\n').filter((line) => !!line); | |||
const contentLines = | |||
typeof blockContent === 'string' ? blockContent.split('\n').filter((line) => !!line) : []; |
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'll be honest... this is definitely a short term solution to get the error not to happen... but I wonder if it's not worth correcting it at the source.
Either way, I think the solution should be to exit early.
(blockContent) => {
if (typeof blockContent !== 'string') return;
//...
}
I think we'd want to type blockContent
as a string. Thus making our typeof
check not a valid check maybe a check one step higher 🤔 .
I think the solution should be to go to co-fetch.js
and handle this situation:
if (response.headers.get('Content-Length') === '0') {
return Promise.resolve({});
}
Or maybe even better by updating the coFetchText
:
export const coFetchText = (url, options = {}, timeout) => {
return coFetchCommon(url, 'GET', options, timeout).then(() => { /* prevent non strings */ });
};
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.
Handled non strings in CoFetchText
, so that the consumer of this method will always get string response.
3f892c2
to
0d4b8f6
Compare
0d4b8f6
to
9631b59
Compare
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 like the solution, I think we can get this one step further though.
frontend/public/co-fetch.js
Outdated
if (_.isObject(response)) { | ||
return _.isEmpty(response) ? '' : JSON.stringify(response); | ||
} | ||
return response; |
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.
return response; | |
return _.toString(response); |
Let's enforce this a bit more. null
=> ''
, false
=> 'false'
. I think this is a good safety to have.
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.
Udpated.
frontend/public/co-fetch.js
Outdated
@@ -164,7 +164,12 @@ export const coFetchJSON = (url, method = 'GET', options = {}, timeout) => { | |||
}; | |||
|
|||
export const coFetchText = (url, options = {}, timeout) => { | |||
return coFetchCommon(url, 'GET', options, timeout); | |||
return coFetchCommon(url, 'GET', options, timeout).then((response) => { |
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.
return coFetchCommon(url, 'GET', options, timeout).then((response) => { | |
return coFetchCommon(url, 'GET', options, timeout).then((response): string => { |
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.
@andrewballantyne I dint change this because this is a co-fetch.js File, i can change it to ts file but all other methods are not typed here. WDYT?
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 hahaha, sorry... on autopilot. Forget we have JS files. Nvm, you are good, ignore this change.
960c062
to
8527339
Compare
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.
frontend/public/co-fetch.js
Outdated
return coFetchCommon(url, 'GET', options, timeout); | ||
return coFetchCommon(url, 'GET', options, timeout).then((response) => { | ||
if (_.isObject(response)) { | ||
return _.isEmpty(response) ? '' : JSON.stringify(response); |
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.
This is odd because we're undoing what coFetchCommon
has provided.
A better solution might be to split coFetchCommon
into 2 functions such that one simply returns the response without calling .text()
or .json()
such that we use it here to return the text.
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 problem with coFetchCommon method is, when the response.headers.get('Content-Length') === '0'
it always resolves an {}
empty object, by conditionally resolving an empty string or an empty object based on response.headers.get('Content-Type')
, we can avoid the undoing logic altogether. WDYT?
8527339
to
9d0e724
Compare
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.
This is a better solution. Was worried this was not going to be possible when I originally logged the ticket as we can't send the accepts
request header for every API... but testing the response on the return might work. I'll need to do a quick test to verify this works as expected. Pretty sure the content reads text/plain when no content is there, but I am unsure if that's 100% true all the time since zero content doesn't really need a type.
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.
@karthikjeeyar tkn
logs omit the step for which there are no logs and we try to show same logs as tkn logs
. Not sure if we should do the same?
cc: @andrewballantyne
As discussed with @sahil143 - this is something we can move to 4.6. We're locking things down for 4.5 and let us just deal with the problems at hand and improve the slightly undesirables later. |
story to track the above issue https://issues.redhat.com/browse/ODC-4002 |
/lgtm |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: andrewballantyne, christianvogt, karthikjeeyar The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@karthikjeeyar: All pull requests linked via external trackers have merged: openshift/console#5539. Bugzilla bug 1839080 has been moved to the MODIFIED state. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Fixes: https://issues.redhat.com/browse/ODC-3725
Problem:
Visiting the pipeline run logs page, the logs component shows the error due to the string method is applied on a object.
Solution:
Add additional checks to make sure the string method is used on a string and if it is not a string added a empty array as a fallback.
Screenshots: