-
Notifications
You must be signed in to change notification settings - Fork 7
Suggestion on Handling errors in Channels #4
Comments
Great question! It inspired me to make a change. As of 0.6.3 you can send promises through channels: const channel = Channel();
(async () => {
try {
const devcorn = await channel.shift();
} catch (exception) {
console.error(`Sorry, no unicorns today.`);
}
})();
await channel.push(
fetch(`https://twitter.com/chjango/status/925787871973400576`)
); Now you can find out idiomatically whether there's an error with each datum. Does that solve your problem? |
Hmm, I'm not sure. What I really want to have is a single promise on the larger operation populating the channel, not each channel item. I've solved this myself for now like this: (sorry, I'm not very es7 fluent yet)
Then in my main code:
Essentially the channel always gets closed, and after the forEach I check the result promise to ensure whether or not I got everything. |
Just an update here, I do like the ability to send a rejection via the channel as it allows my consumer to process all items that do get pushed to the channel up until it hits an error. This simplifies my code a lot. Here's a real Elasticsearch fetcher function that returns a channel exports.search_channel = (query, ch=Channel(100)) ->
do () ->
query.scroll = '30s'
query.size = ch.length
total = 0
loop
try
response = await if total == 0
log.debug "initial fetch"
es_client.search query
else
log.debug "fetching more"
es_client.scroll {
scrollId: response._scroll_id
scroll: '30s'
}
for hit in response.hits.hits
await ch.push hit._source
total += 1
catch err
await ch.push Promise.reject err
break
break unless response.hits.total > total
ch.close()
ch.readOnly() The consumer for this can work like this: channel = es.search_channel { index: "foo", query: "*"}
try
await channel.forEach (record) ->
# process record
catch err
# Fetch error I guess the only thing this lacks is the ability to throw a channel exception that would allow the consumer to stop processing as soon as there is an error, regardless of how many items are in the channel. |
|
This departs a bit from the go spec, but I'm considering how to integrate error handling from my channel writers so my readers know something broke upstream.
My current workflow (pre-channels) is that my "getter" function returns a promise that either resolves with the entire get data set, or throws an error if it encounters something getting that data. The getter function can internally be doing multiple webservice/database calls, any of which may result in an distinct error. In pseudo-code (sorry, I think coffeescript), the workflow is like this:
Under channels, I can return a channel, and I can get data from the channel and know when it is closed, but not if the getter had an error or not.
What I'm wondering is if it makes any sense for a channel writer to be able to throw an exception via the channel so the reader can know the datastream is incomplete:
and on the receiver, I can catch it:
The only other solution to this I can think of is if my getChannel returns both the channel and a separate promise that rejects if there is a processing issue. That seems clunkier however and I then have to process both the channel and the fetching process to ensure I have gotten all my data.
Mostly I'm just suggesting this as a possible feature and I'm interested in your take on it.
The text was updated successfully, but these errors were encountered: