-
Notifications
You must be signed in to change notification settings - Fork 30
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
Streaming results: error appears as a result row #378
Comments
I think this is the same issue as this one: #332. The complication there is that a mid-stream error appears as part of the results, and it is also format-dependant. Unfortunately, the HTTP interface fixes in 24.11+ did not improve the situation in these scenarios. We are currently discussing internally what could be the best approach there, as there are a few major complications:
Currently, the only reliable way to avoid this is to use the import { createClient } from '@clickhouse/client'
void (async () => {
const client = createClient()
try {
let rowsCount = 0
const rs = await client.query({
query: `
SELECT
number,
if(number > 420000, throwIf(1, 'Intentional Error Triggered'), number) AS value
FROM
numbers(1000000)
`,
format: 'JSONEachRow',
clickhouse_settings: {
max_block_size: '1000',
wait_end_of_query: 1,
},
}) // <- the request will fail here due to `wait_end_of_query`
const stream = rs.stream()
for await (const rows of stream) {
rowsCount += rows.length
}
console.log(`Received ${rowsCount} rows`)
} catch (e) {
console.error(e)
}
})() which will now print the following, as the server will immediately respond with 500 ISE instead of 200 OK:
However, this might not be an option if the result sets are too large. |
Thanks for replying @slvrtrn . We don't really need the error to be thrown at the beginning of the query. It might process and return 1B rows before encountering the row with the error. We'd just like the error to be surfaced if and when it happens. We have huge result sets, and I can't imagine buffering is practical -- not to mention, we really do want results to start flowing as soon as possible, since "time to first byte" is critical for our use case. I completely understand the factors you mentioned. This isn't trivial. I'm glad you & others are already considering it. Thank you!! |
Describe the bug
When using
.stream()
to stream rows as JSON, if an error occurs mid-query, the "exception" appears as a row in the results. This effectively means you need to scan the results for a row containing only"exception"
. This is costly (not much, but every bit counts) and silly.If you have a scenario where the query legitimately returns a column named
exception
, then...well you get the point.Initially I used
StreamReadable.on('error', ...)
expecting that listener to be invoked, but it wasn't. On one hand, I guess it makes sense since it wasn't a stream/read related error, but the fact that errors aren't surfaced in a first-class way is a design limitation.Steps to reproduce
Run a query that will produce an error mid-way through, i.e.
Stream that via
ClickHouseClient.query().stream()
. You'll see the row with"exception"
appears among the results.Expected behaviour
Errors should be surfaced in a more first-class way. Proposals:
StreamReadable.on('error', ...)
listener."text"
you could distinguish it as"error"
. This would still require checking each row, far from ideal, but a step in the right direction.Thank you!!
The text was updated successfully, but these errors were encountered: