[Dashboard] Log warning if filter and query state are malformed#230088
[Dashboard] Log warning if filter and query state are malformed#230088nickpeihl merged 8 commits intoelastic:mainfrom
Conversation
|
Pinging @elastic/kibana-presentation (Team:Presentation) |
nreese
left a comment
There was a problem hiding this comment.
I have a question about what to do with errors. I think dashboard API should just store what its given and return what its given in the event of the error. This will allow the UI the chance to display problems so filters and queries just don't magically disappear.
| // If the references can not be extracted, we log a warning | ||
| // and return an empty object to avoid breaking the dashboard saving. | ||
| logger.warn(`Unable to transform filter and query state on save. Error: ${error.message}`); | ||
| return { searchSourceJSON: '{}', references: [] }; |
There was a problem hiding this comment.
You will loss the filter state if you return an empty object. How about returning JSON.stringify(searchSource)?
| } catch (error) { | ||
| // If the searchSourceJSON is malformed or references are missing, we log a warning | ||
| // and return an empty object to avoid breaking the dashboard loading. | ||
| logger.warn(`Unable to transform filter and query state on read. Error: ${error.message}`); |
There was a problem hiding this comment.
how about returning un-injected state. That way the client can display a usable error message and maybe let the user fix the problem?
There was a problem hiding this comment.
Good idea. But should we also handle an error when the searchSourceJSON can not be parsed into an object? Should we throw an error here or log a warning and return the stringified JSON?
There was a problem hiding this comment.
If searchSourceJSON parse fails, then return an empty object for filters and query. I almost wonder if we should include a warnings array in the response to capture failures like these and then display something client side. What do you think?
There was a problem hiding this comment.
If searchSourceJSON parse fails, then return an empty object for filters and query.
Sounds good.
I almost wonder if we should include a warnings array in the response to capture failures like these and then display something client side. What do you think?
I'm not opposed to it. Do you see the warnings array as a top-level item in the response?
for example, something like this?
{
"id": "some-uuid",
"type": "dashboard",
"data": {
"kibanaSavedObjectMeta": { ... },
"panels": [],
...
},
"warnings": [{
"title": "Reference error",
"detail": "Could not find reference for kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index"
}],
}There was a problem hiding this comment.
Yes, something like that would allow the UI to display a warning toast if there are loading issues. I wonder if title is needed. I think dashboard should just display a single toast with bullets for each warning. But I am not against additional context. We could always just not display titles in the client
There was a problem hiding this comment.
@nreese I was thinking about this over the weekend and would like more time to consider if/how we expose different messages between the client and the server. A read-only dashboard user might be confused by a toast message warning about missing references. However, logging these kinds of warnings on the server might have more utility.
I have created this issue for adding a warnings array to the response. But it might be blocked by #196609 since I think the warnings should go in the read-only meta property that will be introduced by that issue.
Also, this PR is fixing a bug in main and serverless and I'd like to prioritized getting this merged before we start exposing warnings in the response and UI. So do you mind if we merge this PR and consider #230314 a separate effort?
Will be fixed in a separate PR.
| const searchSource = injectReferences(parsedSearchSource, references); | ||
| const filters = cleanFiltersForSerialize(searchSource.filter); | ||
| const query = searchSource.query ? migrateLegacyQuery(searchSource.query) : undefined; | ||
| try { |
There was a problem hiding this comment.
Instead of nested try/catch statements how about just
let parsedSearchSource;
try {
parsedSearchSource = parseSearchSourceJSON(searchSourceJSON);
} catch (parseError) {
logger.warn(`Unable to parse searchSourceJSON. Error: ${parseError.message}`);
return { searchSource: {} };
}
let searchSource;
try {
searchSource = injectReferences(parsedSearchSource, references);
} catch (injectError) {
logger.warn(
`Unable to transform filter and query state on read. Error: ${injectError.message}`
);
// fallback to parsed if injection fails
searchSource = parsedSearchSource;
}
try {
const filters = cleanFiltersForSerialize(searchSource.filter);
const query = searchSource.query ? migrateLegacyQuery(searchSource.query) : undefined;
return { searchSource: { filters, query } };
} catch (error) {
logger.warn(
`Unexpected error transforming filter and query state on read. Error: ${error.message}`
);
return {
searchSource: {
filters: searchSource.filter,
query: searchSource.query,
}
};
}
| logger.warn( | ||
| `Unexpected error transforming filter and query state on read. Error: ${error.message}` | ||
| ); | ||
| return { searchSource: {} }; |
There was a problem hiding this comment.
This should return
searchSource: {
filters: searchSource.filter,
query: searchSource.query,
}
nreese
left a comment
There was a problem hiding this comment.
kibana-presentation changes LGTM
code review only
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]
History
|
Fixes #230054
Summary
Logs a warning instead of throwing an error if filter and query state can not be read or written due to missing or malformed references.
Also removes unnecessary Promises in the Dashboard server search and get methods.