[#3038] Add RecordListener.exception(RecordContext) and RecordContext.exception()
This commit is contained in:
parent
68e4294f16
commit
e7f3e241bc
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,4 +89,7 @@ public class DefaultRecordListener implements RecordListener {
|
||||
@Override
|
||||
public void refreshEnd(RecordContext ctx) {}
|
||||
|
||||
@Override
|
||||
public void exception(RecordContext ctx) {}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user