[jOOQ/jOOQ#15085] Confusing error message when reading a non-existing
Field from a Record containing accidentally nested row types
This commit is contained in:
parent
6a42a7e888
commit
d47a597431
@ -386,7 +386,7 @@ implements
|
||||
if (index >= 0 && index < values.length)
|
||||
return index;
|
||||
|
||||
throw new IllegalArgumentException("No field at index " + index + " in Record type " + fields);
|
||||
throw indexFail(fields, index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -38,9 +38,11 @@
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.QueryPartListView.wrap;
|
||||
import static org.jooq.impl.Tools.EMPTY_FIELD;
|
||||
import static org.jooq.impl.Tools.converterOrFail;
|
||||
import static org.jooq.impl.Tools.indexFail;
|
||||
import static org.jooq.impl.Tools.indexOrFail;
|
||||
import static org.jooq.impl.Tools.map;
|
||||
import static org.jooq.impl.Tools.newRecord;
|
||||
@ -78,7 +80,14 @@ import org.jooq.tools.JooqLogger;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class FieldsImpl<R extends Record> extends AbstractQueryPart implements RecordType<R>, Mappable<R>, UTransient {
|
||||
final class FieldsImpl<R extends Record>
|
||||
extends
|
||||
AbstractQueryPart
|
||||
implements
|
||||
RecordType<R>,
|
||||
Mappable<R>,
|
||||
UTransient
|
||||
{
|
||||
|
||||
private static final JooqLogger log = JooqLogger.getLogger(FieldsImpl.class);
|
||||
Field<?>[] fields;
|
||||
@ -407,7 +416,7 @@ final class FieldsImpl<R extends Record> extends AbstractQueryPart implements Re
|
||||
if (index >= 0 && index < fields.length)
|
||||
return index;
|
||||
|
||||
throw new IllegalArgumentException("No field at index " + index + " in Record type " + fields);
|
||||
throw indexFail(this, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -660,4 +669,9 @@ final class FieldsImpl<R extends Record> extends AbstractQueryPart implements Re
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return row(fields).toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Records.intoList;
|
||||
import static org.jooq.Records.intoResultGroups;
|
||||
import static org.jooq.impl.Tools.indexFail;
|
||||
import static org.jooq.impl.Tools.indexOrFail;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
@ -1068,7 +1069,7 @@ final class ResultImpl<R extends Record> extends AbstractResult<R> implements Re
|
||||
if (index >= 0 && index < fields.size())
|
||||
return index;
|
||||
|
||||
throw new IllegalArgumentException("No field at index " + index + " in Record type " + fields);
|
||||
throw indexFail(fields, index);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -2238,7 +2238,26 @@ final class Tools {
|
||||
}
|
||||
|
||||
static final IllegalArgumentException indexFail(Fields row, Field<?> field) {
|
||||
return new IllegalArgumentException("Field (" + field + ") is not contained in Row " + row);
|
||||
if (lookupNested(row, field))
|
||||
return new IllegalArgumentException("Field " + field + " is not contained at the top level of row type containing nested row types. Unnest the nested row type first and access the field from there: " + row);
|
||||
else
|
||||
return new IllegalArgumentException("Field " + field + " is not contained in row type " + row);
|
||||
}
|
||||
|
||||
private static final boolean lookupNested(Fields row, Field<?> field) {
|
||||
|
||||
// [#15085] [#16721] Help users spot the problem if they accidentally nest row types
|
||||
if (row.field(field) != null)
|
||||
return true;
|
||||
|
||||
for (Field<?> f : row.fields()) {
|
||||
if (f instanceof AbstractRowAsField<?> rf) {
|
||||
if (lookupNested(rf.fields0(), field))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static final int indexOrFail(Fields row, Field<?> field) {
|
||||
@ -2251,7 +2270,7 @@ final class Tools {
|
||||
}
|
||||
|
||||
static final IllegalArgumentException indexFail(Fields row, String fieldName) {
|
||||
throw new IllegalArgumentException("Field (" + fieldName + ") is not contained in Row " + row);
|
||||
return indexFail(row, DSL.name(fieldName));
|
||||
}
|
||||
|
||||
static final int indexOrFail(Fields row, String fieldName) {
|
||||
@ -2264,7 +2283,7 @@ final class Tools {
|
||||
}
|
||||
|
||||
static final IllegalArgumentException indexFail(Fields row, Name fieldName) {
|
||||
throw new IllegalArgumentException("Field (" + fieldName + ") is not contained in Row " + row);
|
||||
return indexFail(row, DSL.field(fieldName));
|
||||
}
|
||||
|
||||
static final int indexOrFail(Fields row, Name fieldName) {
|
||||
@ -2277,7 +2296,23 @@ final class Tools {
|
||||
}
|
||||
|
||||
static final IllegalArgumentException indexFail(Fields row, int fieldIndex) {
|
||||
throw new IllegalArgumentException("Field (" + fieldIndex + ") is not contained in Row " + row);
|
||||
if (fieldIndex < countFlattened(row, 0))
|
||||
return new IllegalArgumentException("No field at index " + fieldIndex + " is not contained at the top level of row type containing nested row types. Unnest the nested row types first and access the field from there: " + row);
|
||||
else
|
||||
return new IllegalArgumentException("No field at index " + fieldIndex + " in row type " + row);
|
||||
}
|
||||
|
||||
private static final int countFlattened(Fields row, int count) {
|
||||
|
||||
// [#15085] [#16721] Help users spot the problem if they accidentally nest row types
|
||||
for (Field<?> f : row.fields()) {
|
||||
if (f instanceof AbstractRowAsField<?> rf)
|
||||
count += countFlattened(rf.fields0(), count);
|
||||
else
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static final int indexOrFail(Fields row, int fieldIndex) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user