RE: [indexeddb] Implicit Transaction Request associated with failed transactions

On Tuesday, November 08, 2011 2:09 PM, David Grogan wrote:
>On Wed, Oct 26, 2011 at 4:36 PM, Israel Hilerio <israelh@microsoft.com> wrote:
>>On Friday, October 14, 2011 2:33 PM, Jonas Sicking wrote:
>>> > The firing of error events on the transaction should only be of two types:
>>> propagation error events or transaction error events.
>>> >
>>> > This should allow devs the ability to handle data error objects inside their
>>> IDBRequest.onerror handler and transaction commit error on their
>>> IDBTransaction.onerror handler.  The only difference is that QuotaError and
>>> TimeoutError would wouldn't be cancellable and will always bubble.
>>>
>>> Not quite sure what you mean by "propagation error events". Do you mean
>>> events that are fired on a request, but where the transaction.onerror handler
>>> is called during the event's bubble phase?
>>>
>>> If so I think this sounds good. However there's still the matter of defining
>>> when a "transaction error event" should be fired.
>>> Transactions currently fail to commit in at least the following
>>> circumstances:

>>Yes, by "propagation error events" I meant events that are fired on a request, but where the transaction.onerror handler is called during the event's bubble phase.

>>> A) When transaction.abort() is explicitly called
>>> B) When a .put or .add request fails due to a 'unique' constraint violation in an
>>> index, and the result "error" event *isn't* canceled using
>>> event.preventDefault()
>>> C) When an exception is thrown during a event handler for a "error" event
>>> D) When an exception is thrown during a event handler for a "success" event
>>> E) When a index is created with a 'unique' constraint on an objectStore which
>>> already has data which violates the constraint.
>>> F) When a request fails due to database error (for example IO error) and the
>>> resulting "error" event *isn't* canceled using
>>> event.preventDefault()
>>> G) When a transaction fails to commit due to a quota error
>>> H) When a transaction fails to commit due to a IO error
>>> I) When a transaction fails to commit due to a timeout error
>>
>>Great list :-)
>>
>>>
>>> I've probably missed some places too.
>>>
>>> In which of these occasions do you think we should fire an "error"
>>> event on the transaction before firing the "abort" event? And note that in
>>> *all* of the above cases we will fire a "abort" event on the transaction.
>>>
>>> >From the discussion so far, it sounds like you *don't* want to fire an
>>> "error" event for at least for situation A, which makes sense to me.
>>>
>>> Whatever situations we decide to fire an "error" event in, I'd like there to be
>>> some sort of consistency. I'd also like to start by looking at use cases rather
>>> than just at random pick situations that seem good.
>>>
>>> So, if anyone think we should fire error events targeted at the transaction in
>>> any of the above situations, please state use cases, and which of the above
>>> situations you think should generate an error event.
>>>
>>> Additionally, I'm not sure that we need to worry about I) above. I) only
>>> happens when there are timeouts specified, which only is possible in the
>>> synchronous API. But in the synchronous API we never fire any events, but
>>> simply let IDBDatabaseSync.transaction throw an exception.
>>>
>>> / Jonas
>>
>>I believe that error events on the transaction should be fired for individual request related issues:
>>B) When a .put or .add request fails due to a 'unique' constraint violation in an index, and the result "error" event *isn't* canceled using event.preventDefault()
>>C) When an exception is thrown during an event handler for a "error" event
>>D) When an exception is thrown during an event handler for a "success" event
>>E) When an index is created with a 'unique' constraint on an objectStore which already has data which violates the constraint.
>>F) When a request fails due to database error (for example IO error) and the resulting "error" event *isn't* canceled using event.preventDefault()
>>
>>However, I don't believe we should fire error events on the transaction for transaction related issues:
>>G) When a transaction fails to commit due to a quota error
>>H) When a transaction fails to commit due to a IO error
>>
>>My fundamental argument is that these are two different types of error cases, request and fatal errors.  I believe that developers want to handle request errors because 
>>they can do something about them.  These request errors are reflections of problems related to individual requests (i.e. add, put, delete record issues or schema related >>issues).  Preventing their default behavior will allow devs to add 99 records into the db but ignore the last 1 record that failed without having to restart the >>transaction.

>>On the other hand, fatal errors are different. They are associated with a backend problem that is not necessarily a reflection of a single request problem but a larger db 
>>issue.  The developer was adding 100 records and they ran out of space at record 57.  Can we guarantee that at this point the system can continue to work without 
>>any side effects?  Do we or can we honor the preventDefault behavior? I don't believe we can guarantee anything when fatal error occur.  It seems to me that 
>>surfacing fatal errors at the same level as regular errors could lead to confusion or frustration among developers since these errors can't be handled in the same 
>>fashion as request errors.

>>I'm open to ideas on how we surface these fatal errors.  I was suggesting for them not to be exposed as error events on the transaction to avoid a possible developer 
>>confusion.
 
>Maybe we can avoid confusion by having *only* fatal errors and not request errors fire error events targeted at the transaction.  Currently, the fatal errors (G and H) 
>are the only errors that the developer has no information about, they just get their transaction aborted with no explanation.

>It is already a problem in chromium.  We sometimes only notice that quota has been exhausted on commit, after firing success for each add operation.  When, on 
>commit, chromium discovers there's not enough quota for all the records, we abort the transaction, but there's no way to report the cause.  An avenue to provide the 
>developer with an explanation is what we're hoping to get out of this thread.  An error event targeted at transaction or just an error attribute on IDBTransaction would 
>do the trick.

>For B - F, the developer already has a mechanism to discover what happened, an additional error event for those cases would be redundant.  In sum, I think if we fire 
>an additional error event it should be in cases G and H, at most.

David,

One advantage of surfacing individual error requests on the transaction error handler is that it provides a single/common place for developers to handle all transaction related errors.  Otherwise, developers would have to handle errors on each individual request which could be annoying.

During the IDB review @ TPAC we talked about NOT surfacing fatal error events (G & H) on the transaction error handler but instead surfacing them on the abort handler.  We will continue to surface all individual requests errors on the transaction onerror handler.  One reason was that fata errors can't be undone and developers will get frustrated if they attempt to prevent the default behavior of the event from happening.  However, individual requests errors (with the exception of UnknownError) can generally be undone without major consequences. Based on your scenario, it seems that the proposed approach would deal with your situation.

What do you think?

Israel

Received on Wednesday, 9 November 2011 00:56:00 UTC