[jOOQ/jOOQ#12785] Add DiagnosticsListener::exception to handle exceptions encountered while running diagnostics

This commit is contained in:
Lukas Eder 2022-01-06 11:32:45 +01:00
parent 5e5645460b
commit 55cefa26fb
6 changed files with 93 additions and 30 deletions

View File

@ -172,4 +172,10 @@ public interface DiagnosticsContext {
*/
@NotNull
List<String> repeatedStatements();
/**
* The exception that occurred while diagnosing a statement.
*/
@Nullable
Throwable exception();
}

View File

@ -42,6 +42,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.jooq.impl.DSL;
import org.jooq.impl.ParserException;
/**
* A diagnostics listener.
@ -203,4 +204,18 @@ public interface DiagnosticsListener {
/**
* Something went wrong while diagnosing a SQL query.
* <p>
* The actual exception will be provided by
* {@link DiagnosticsContext#exception()}. Likely exceptions include:
* <ul>
* <li>A {@link ParserException} because jOOQ couldn't parse user defined
* SQL.</li>
* <li>A user exception from a custom {@link DiagnosticsListener}
* implementation.</li>
* </ul>
*/
void exception(DiagnosticsContext ctx);
}

View File

@ -39,6 +39,8 @@ package org.jooq.impl;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
@ -72,16 +74,34 @@ final class DefaultDiagnosticsContext implements DiagnosticsContext {
boolean resultSetUnnecessaryWasNullCall;
boolean resultSetMissingWasNullCall;
int resultSetColumnIndex;
final Throwable exception;
DefaultDiagnosticsContext(String actualStatement) {
this(actualStatement, actualStatement, Collections.singleton(actualStatement), Collections.singletonList(actualStatement));
this(actualStatement, null);
}
DefaultDiagnosticsContext(String actualStatement, String normalisedStatement, Set<String> duplicateStatements, List<String> repeatedStatements) {
DefaultDiagnosticsContext(String actualStatement, Throwable exception) {
this(
actualStatement,
actualStatement,
singleton(actualStatement),
singletonList(actualStatement),
exception
);
}
DefaultDiagnosticsContext(
String actualStatement,
String normalisedStatement,
Set<String> duplicateStatements,
List<String> repeatedStatements,
Throwable exception
) {
this.actualStatement = actualStatement;
this.normalisedStatement = normalisedStatement;
this.duplicateStatements = duplicateStatements == null ? emptySet() : duplicateStatements;
this.repeatedStatements = repeatedStatements == null ? emptyList() : repeatedStatements;
this.exception = exception;
}
@Override
@ -185,4 +205,9 @@ final class DefaultDiagnosticsContext implements DiagnosticsContext {
public final List<String> repeatedStatements() {
return Collections.unmodifiableList(repeatedStatements);
}
@Override
public final Throwable exception() {
return exception;
}
}

View File

@ -73,4 +73,6 @@ public class DefaultDiagnosticsListener implements DiagnosticsListener {
@Override
public void exception(DiagnosticsContext ctx) {}
}

View File

@ -169,38 +169,47 @@ final class DiagnosticsConnection extends DefaultConnection {
queries = parser.parse(sql);
normalised = normalisingRenderer.render(queries);
}
catch (ParserException ignore) {
catch (ParserException exception) {
normalised = sql;
listeners.exception(new DefaultDiagnosticsContext(sql, exception));
}
Set<String> duplicates;
synchronized (DUPLICATE_SQL) {
duplicates = duplicates(DUPLICATE_SQL, sql, normalised);
try {
Set<String> duplicates = null;
synchronized (DUPLICATE_SQL) {
duplicates = duplicates(DUPLICATE_SQL, sql, normalised);
}
if (duplicates != null)
listeners.duplicateStatements(new DefaultDiagnosticsContext(sql, normalised, duplicates, null, null));
List<String> repetitions = repetitions(repeatedSQL, sql, normalised);
if (repetitions != null)
listeners.repeatedStatements(new DefaultDiagnosticsContext(sql, normalised, null, repetitions, null));
}
catch (Error e) {
throw e;
}
catch (Throwable exception) {
listeners.exception(new DefaultDiagnosticsContext(sql, normalised, null, null, exception));
}
if (duplicates != null)
listeners.duplicateStatements(new DefaultDiagnosticsContext(sql, normalised, duplicates, null));
List<String> repetitions = repetitions(repeatedSQL, sql, normalised);
if (repetitions != null)
listeners.repeatedStatements(new DefaultDiagnosticsContext(sql, normalised, null, repetitions));
return sql;
}

View File

@ -104,4 +104,10 @@ final class DiagnosticsListeners implements DiagnosticsListener {
@Override
public final void exception(DiagnosticsContext ctx) {
for (DiagnosticsListener listener : listeners)
listener.exception(ctx);
}
}