[#3038] Add RecordListener.exception(RecordContext) and RecordContext.exception()

This commit is contained in:
Lukas Eder 2014-02-12 16:43:04 +01:00
parent 68e4294f16
commit e7f3e241bc
6 changed files with 49 additions and 13 deletions

View File

@ -186,6 +186,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
catch (DataAccessException expected) {}
assertEquals(asList("insertStart", "insertEnd"), listener1.events);
assertEquals(1, listener1.exceptions.size());
}
@Test
@ -224,6 +225,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
private static class WriteListener extends DefaultRecordListener {
List<String> events = new ArrayList<String>();
List<Exception> exceptions = new ArrayList<Exception>();
@Override
public void storeStart(RecordContext ctx) {
@ -264,5 +266,10 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
public void deleteEnd(RecordContext ctx) {
events.add("deleteEnd");
}
@Override
public void exception(RecordContext ctx) {
exceptions.add(ctx.exception());
}
}
}

View File

@ -43,8 +43,8 @@ package org.jooq;
import java.util.Map;
/**
* A context object for {@link Record} manipulation passed to
* registered {@link RecordListener}'s.
* A context object for {@link Record} manipulation passed to registered
* {@link RecordListener}'s.
*
* @author Lukas Eder
*/
@ -137,15 +137,20 @@ public interface RecordContext {
Record record();
/**
* The <code>Record</code>(s) that are being manipulated in batch
* mode.
* The <code>Record</code>(s) that are being manipulated in batch mode.
* <p>
* If a single <code>Record</code> is being manipulated in
* non-batch mode, this will return an array of length <code>1</code>,
* containing that <code>Record</code>.
* If a single <code>Record</code> is being manipulated in non-batch mode,
* this will return an array of length <code>1</code>, containing that
* <code>Record</code>.
*
* @return The <code>Record</code>(s) being manipulated. This is
* never <code>null</code>
* @return The <code>Record</code>(s) being manipulated. This is never
* <code>null</code>
*/
Record[] batchRecords();
/**
* The {@link Exception} being thrown or <code>null</code>.
*/
Exception exception();
}

View File

@ -191,4 +191,9 @@ public interface RecordListener extends EventListener {
* @see UpdatableRecord#refresh()
*/
void refreshEnd(RecordContext ctx);
/**
* Called when an exception occurs.
*/
void exception(RecordContext ctx);
}

View File

@ -59,6 +59,7 @@ class DefaultRecordContext implements RecordContext {
private final HashMap<Object, Object> data;
private final ExecuteType type;
private final Record[] records;
Exception exception;
DefaultRecordContext(Configuration configuration, ExecuteType type, Record... records) {
this.configuration = configuration;
@ -101,4 +102,9 @@ class DefaultRecordContext implements RecordContext {
public final Record[] batchRecords() {
return records;
}
@Override
public final Exception exception() {
return exception;
}
}

View File

@ -89,4 +89,7 @@ public class DefaultRecordListener implements RecordListener {
@Override
public void refreshEnd(RecordContext ctx) {}
@Override
public void exception(RecordContext ctx) {}
}

View File

@ -48,9 +48,9 @@ import static org.jooq.impl.RecordDelegate.RecordLifecycleType.REFRESH;
import org.jooq.Configuration;
import org.jooq.ExecuteType;
import org.jooq.Record;
import org.jooq.RecordContext;
import org.jooq.RecordListener;
import org.jooq.RecordListenerProvider;
import org.jooq.exception.ControlFlowSignal;
/**
* A stub for {@link Record} objects, abstracting {@link RecordListener}
@ -86,7 +86,7 @@ class RecordDelegate<R extends Record> {
final <E extends Exception> R operate(RecordOperation<R, E> operation) throws E {
RecordListenerProvider[] providers = null;
RecordListener[] listeners = null;
RecordContext ctx = null;
DefaultRecordContext ctx = null;
E exception = null;
if (configuration != null) {
@ -103,7 +103,7 @@ class RecordDelegate<R extends Record> {
}
if (listeners != null) {
for (RecordListener listener : listeners) {
for (RecordListener listener : listeners) {
switch (type) {
case LOAD: listener.loadStart(ctx); break;
case REFRESH: listener.refreshStart(ctx); break;
@ -125,11 +125,21 @@ class RecordDelegate<R extends Record> {
// [#2770][#3036] Exceptions must not propagate before listeners receive "end" events
catch (Exception e) {
exception = (E) e;
// Do not propagate these exception types to client code as they're not really "exceptions"
if (!(e instanceof ControlFlowSignal)) {
if (ctx != null)
ctx.exception = e;
if (listeners != null)
for (RecordListener listener : listeners)
listener.exception(ctx);
}
}
}
if (listeners != null) {
for (RecordListener listener : listeners) {
for (RecordListener listener : listeners) {
switch (type) {
case LOAD: listener.loadEnd(ctx); break;
case REFRESH: listener.refreshEnd(ctx); break;