Improve error message for invalid date param (#2466)

* Improve error message for invalid date param

* Add changelog

* Test fixes
This commit is contained in:
James Agnew 2021-03-11 14:23:02 -05:00 committed by GitHub
parent 950e65dc48
commit 2633cbd141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 9 deletions

View File

@ -56,6 +56,10 @@ public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam
offset++;
}
if (offset > 0 && theString.length() == offset) {
throw new DataFormatException("Invalid date/time format: \"" + theString + "\"");
}
String prefix = theString.substring(0, offset);
if (!isBlank(prefix)) {

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.rest.param;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.api.QualifiedParamList;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -10,6 +11,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public class DateRangeParamTest {
private FhirContext fhirContext;
@ -19,7 +21,9 @@ public class DateRangeParamTest {
fhirContext = Mockito.mock(FhirContext.class);
}
/** Can happen e.g. when the query parameter for {@code _lastUpdated} is left empty. */
/**
* Can happen e.g. when the query parameter for {@code _lastUpdated} is left empty.
*/
@Test
public void testParamWithoutPrefixAndWithoutValue() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
@ -33,7 +37,9 @@ public class DateRangeParamTest {
assertTrue(dateRangeParam.isEmpty());
}
/** Can happen e.g. when the query parameter for {@code _lastUpdated} is given as {@code lt} without any value. */
/**
* Can happen e.g. when the query parameter for {@code _lastUpdated} is given as {@code lt} without any value.
*/
@Test
public void testUpperBoundWithPrefixWithoutValue() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
@ -42,12 +48,17 @@ public class DateRangeParamTest {
List<QualifiedParamList> params = new ArrayList<>(1);
params.add(qualifiedParamList);
DateRangeParam dateRangeParam = new DateRangeParam();
dateRangeParam.setValuesAsQueryTokens(fhirContext, "_lastUpdated", params);
assertTrue(dateRangeParam.isEmpty());
try {
dateRangeParam.setValuesAsQueryTokens(fhirContext, "_lastUpdated", params);
fail();
} catch (DataFormatException e) {
// good
}
}
/** Can happen e.g. when the query parameter for {@code _lastUpdated} is given as {@code gt} without any value. */
/**
* Can happen e.g. when the query parameter for {@code _lastUpdated} is given as {@code gt} without any value.
*/
@Test
public void testLowerBoundWithPrefixWithoutValue() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
@ -56,8 +67,11 @@ public class DateRangeParamTest {
List<QualifiedParamList> params = new ArrayList<>(1);
params.add(qualifiedParamList);
DateRangeParam dateRangeParam = new DateRangeParam();
dateRangeParam.setValuesAsQueryTokens(fhirContext, "_lastUpdated", params);
assertTrue(dateRangeParam.isEmpty());
try {
dateRangeParam.setValuesAsQueryTokens(fhirContext, "_lastUpdated", params);
fail();
} catch (DataFormatException e) {
// good
}
}
}

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 2466
title: "When performainfg a search using a date search parameter, invalid values (e.g. `date=foo`) resulted
in a confusing error message. This has been improved."

View File

@ -333,6 +333,32 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
@Test
public void testSearchWithDateInvalid() throws IOException {
HttpGet get = new HttpGet(ourServerBase + "/Condition?onset-date=junk");
try (CloseableHttpResponse resp = ourHttpClient.execute(get)) {
String output = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
assertThat(output, containsString("Invalid date/time format: &quot;junk&quot;"));
assertEquals(400, resp.getStatusLine().getStatusCode());
}
get = new HttpGet(ourServerBase + "/Condition?onset-date=ge");
try (CloseableHttpResponse resp = ourHttpClient.execute(get)) {
String output = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
assertThat(output, containsString("Invalid date/time format: &quot;ge&quot;"));
assertEquals(400, resp.getStatusLine().getStatusCode());
}
get = new HttpGet(ourServerBase + "/Condition?onset-date=" + UrlUtil.escapeUrlParam(">"));
try (CloseableHttpResponse resp = ourHttpClient.execute(get)) {
String output = IOUtils.toString(resp.getEntity().getContent(), Charsets.UTF_8);
assertThat(output, containsString("Invalid date/time format: &quot;&gt;&quot;"));
assertEquals(400, resp.getStatusLine().getStatusCode());
}
}
@Test
public void testSearchWithSlashes() {
myDaoConfig.setSearchPreFetchThresholds(Lists.newArrayList(10, 50, 10000));