From e72fcda5fe7c2f020fc6d0765e554485e61a2c95 Mon Sep 17 00:00:00 2001 From: Francesco Date: Sat, 30 Sep 2023 10:16:06 +0200 Subject: [PATCH] Better error handling of invalid values in faceted search --- .../controller/DefaultDbAdminController.java | 11 +++++++++++ .../external/dbmapping/CustomJpaRepository.java | 7 ++++++- .../ailef/dbadmin/external/dto/QueryFilter.java | 5 ++++- .../tech/ailef/dbadmin/external/misc/Utils.java | 14 +++++++++++--- src/main/resources/templates/fragments/forms.html | 4 ++-- src/main/resources/templates/model/list.html | 8 +++++--- 6 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/main/java/tech/ailef/dbadmin/external/controller/DefaultDbAdminController.java b/src/main/java/tech/ailef/dbadmin/external/controller/DefaultDbAdminController.java index 5d38673..5260374 100644 --- a/src/main/java/tech/ailef/dbadmin/external/controller/DefaultDbAdminController.java +++ b/src/main/java/tech/ailef/dbadmin/external/controller/DefaultDbAdminController.java @@ -37,6 +37,7 @@ import tech.ailef.dbadmin.external.dto.FacetedSearchRequest; import tech.ailef.dbadmin.external.dto.LogsSearchRequest; import tech.ailef.dbadmin.external.dto.PaginatedResult; import tech.ailef.dbadmin.external.dto.QueryFilter; +import tech.ailef.dbadmin.external.exceptions.DbAdminException; import tech.ailef.dbadmin.external.exceptions.InvalidPageException; import tech.ailef.dbadmin.external.misc.Utils; import tech.ailef.dbadmin.internal.model.UserAction; @@ -184,6 +185,16 @@ public class DefaultDbAdminController { } catch (InvalidPageException e) { return "redirect:/" + properties.getBaseUrl() + "/model/" + className; + } catch (DbAdminException e) { + model.addAttribute("error", e.getMessage()); + model.addAttribute("errorTitle", "Invalid request"); + model.addAttribute("schema", schema); + model.addAttribute("activePage", "entities"); + model.addAttribute("sortKey", sortKey); + model.addAttribute("query", query); + model.addAttribute("sortOrder", sortOrder); + model.addAttribute("activeFilters", queryFilters); + return "model/list"; } } diff --git a/src/main/java/tech/ailef/dbadmin/external/dbmapping/CustomJpaRepository.java b/src/main/java/tech/ailef/dbadmin/external/dbmapping/CustomJpaRepository.java index 90b32ef..f395492 100644 --- a/src/main/java/tech/ailef/dbadmin/external/dbmapping/CustomJpaRepository.java +++ b/src/main/java/tech/ailef/dbadmin/external/dbmapping/CustomJpaRepository.java @@ -153,7 +153,12 @@ public class CustomJpaRepository extends SimpleJpaRepository { String fieldName = dbField.getJavaName(); String v = filter.getValue(); - Object value = dbField.getType().parseValue(v); + Object value; + try { + value = dbField.getType().parseValue(v); + } catch (Exception e) { + throw new DbAdminException("Invalid value `" + v + "` specified for field `" + dbField.getName() + "`"); + } if (op == CompareOperator.STRING_EQ) { if (value == null) diff --git a/src/main/java/tech/ailef/dbadmin/external/dto/QueryFilter.java b/src/main/java/tech/ailef/dbadmin/external/dto/QueryFilter.java index e983269..f385516 100644 --- a/src/main/java/tech/ailef/dbadmin/external/dto/QueryFilter.java +++ b/src/main/java/tech/ailef/dbadmin/external/dto/QueryFilter.java @@ -3,6 +3,7 @@ package tech.ailef.dbadmin.external.dto; import java.util.Objects; import tech.ailef.dbadmin.external.dbmapping.DbField; +import tech.ailef.dbadmin.external.exceptions.DbAdminException; /** * A single filter in a FacetedSearchRequest. This describes a @@ -16,6 +17,8 @@ public class QueryFilter { private String value; public QueryFilter(DbField field, CompareOperator op, String value) { + if (field == null) + throw new DbAdminException("Trying to build QueryFilter with null `field`"); this.field = field; this.op = op; this.value = value; @@ -53,7 +56,7 @@ public class QueryFilter { public String toString() { if (value != null && !value.toString().isBlank()) { String displayValue = value; - if (value.length() > 10) { + if (value.length() > 18) { displayValue = value.substring(0, 4) + "..." + value.substring(value.length() - 4); } return "'" + field.getName() + "' " + op.getDisplayName() + " '" + displayValue + "'"; diff --git a/src/main/java/tech/ailef/dbadmin/external/misc/Utils.java b/src/main/java/tech/ailef/dbadmin/external/misc/Utils.java index a060bbb..1ee5604 100644 --- a/src/main/java/tech/ailef/dbadmin/external/misc/Utils.java +++ b/src/main/java/tech/ailef/dbadmin/external/misc/Utils.java @@ -7,6 +7,7 @@ import java.util.Set; import org.springframework.util.MultiValueMap; +import tech.ailef.dbadmin.external.dbmapping.DbField; import tech.ailef.dbadmin.external.dbmapping.DbObjectSchema; import tech.ailef.dbadmin.external.dto.CompareOperator; import tech.ailef.dbadmin.external.dto.QueryFilter; @@ -81,9 +82,16 @@ public interface Utils { String op = ops.get(i); String field = fields.get(i); String value = values.get(i); - - QueryFilter queryFilter = new QueryFilter(schema.getFieldByJavaName(field), CompareOperator.valueOf(op.toUpperCase()), value); - filters.add(queryFilter); + + // Check if the field can actually be found before creating the filter + // This shouldn't normally happen because this parameter is not provided + // by the user; but there's the chance of a stale bookmarked link referring + // to a non-existing schema or the user fiddling with the URL + DbField dbField = schema.getFieldByJavaName(field); + if (dbField != null) { + QueryFilter queryFilter = new QueryFilter(dbField, CompareOperator.valueOf(op.toUpperCase()), value); + filters.add(queryFilter); + } } return filters; diff --git a/src/main/resources/templates/fragments/forms.html b/src/main/resources/templates/fragments/forms.html index f2d76b3..3ac8e90 100644 --- a/src/main/resources/templates/fragments/forms.html +++ b/src/main/resources/templates/fragments/forms.html @@ -59,7 +59,7 @@
- + @@ -139,7 +139,7 @@ - + diff --git a/src/main/resources/templates/model/list.html b/src/main/resources/templates/model/list.html index fa68632..44258aa 100644 --- a/src/main/resources/templates/model/list.html +++ b/src/main/resources/templates/model/list.html @@ -47,7 +47,7 @@ + th:value="${page != null ? page.getPagination().getPageSize() : '50'}">
@@ -67,8 +67,10 @@
-
-
+ +
+
+