Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAI-PMH error handling: meaningful errors in XML for verb processing #10205

Merged
merged 9 commits into from
Jan 17, 2024
4 changes: 4 additions & 0 deletions doc/release-notes/9275-harvest-invalid-query-params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
OAI-PMH error handling has been improved to display a machine-readable error in XML rather than a 500 error with no further information.

- /oai?foo=bar will show "No argument 'verb' found"
- /oai?verb=foo&verb=bar will show "Verb must be singular, given: '[foo, bar]'"
3 changes: 3 additions & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ services:
DATAVERSE_AUTH_OIDC_CLIENT_SECRET: 94XHrfNRwXsjqTqApRrwWmhDLDHpIYV8
DATAVERSE_AUTH_OIDC_AUTH_SERVER_URL: http://keycloak.mydomain.com:8090/realms/test
DATAVERSE_JSF_REFRESH_PERIOD: "1"
# to get HarvestingServerIT to pass
dataverse_oai_server_maxidentifiers: "2"
dataverse_oai_server_maxrecords: "2"
JVM_ARGS: -Ddataverse.files.storage-driver-id=file1
-Ddataverse.files.file1.type=file
-Ddataverse.files.file1.label=Filesystem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import edu.harvard.iq.dataverse.util.MailUtil;
import edu.harvard.iq.dataverse.util.SystemConfig;
import io.gdcc.xoai.exceptions.BadArgumentException;
import io.gdcc.xoai.exceptions.BadVerbException;
import io.gdcc.xoai.exceptions.OAIException;
import io.gdcc.xoai.model.oaipmh.Granularity;
import io.gdcc.xoai.model.oaipmh.verbs.Verb;
import io.gdcc.xoai.services.impl.SimpleResumptionTokenFormat;
import org.apache.commons.lang3.StringUtils;

Expand Down Expand Up @@ -256,9 +259,18 @@ private void processRequest(HttpServletRequest httpServletRequest, HttpServletRe
"Sorry. OAI Service is disabled on this Dataverse node.");
return;
}

RawRequest rawRequest = RequestBuilder.buildRawRequest(httpServletRequest.getParameterMap());


RawRequest rawRequest = null;
try {
rawRequest = RequestBuilder.buildRawRequest(httpServletRequest.getParameterMap());
} catch (BadVerbException bve) {
// Verb.Type is required. Hard-code one.
rawRequest = new RawRequest(Verb.Type.Identify);
// Ideally, withError would accept a BadVerbException.
BadArgumentException bae = new BadArgumentException(bve.getLocalizedMessage());
rawRequest.withError(bae);
pdurbin marked this conversation as resolved.
Show resolved Hide resolved
}

OAIPMH handle = dataProvider.handle(rawRequest);
response.setContentType("text/xml;charset=UTF-8");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,40 @@ public void testMultiRecordOaiSet() throws InterruptedException {
logger.info("deleteResponse.getStatusCode(): " + deleteResponse.getStatusCode());
assertEquals(200, deleteResponse.getStatusCode(), "Failed to delete the control multi-record set");
}


@Test
public void testInvalidQueryParams() {

// The query parameter "verb" must appear.
Response noVerbArg = given().get("/oai?foo=bar");
noVerbArg.prettyPrint();
noVerbArg.then().assertThat()
.statusCode(OK.getStatusCode())
// This should be "badVerb"
.body("oai.error.@code", equalTo("badArgument"))
.body("oai.error", equalTo("No argument 'verb' found"));

// The query parameter "verb" cannot appear more than once.
Response repeated = given().get( "/oai?verb=foo&verb=bar");
repeated.prettyPrint();
repeated.then().assertThat()
.statusCode(OK.getStatusCode())
// This should be "badVerb"
.body("oai.error.@code", equalTo("badArgument"))
.body("oai.error", equalTo("Verb must be singular, given: '[foo, bar]'"));

}

@Test
public void testNoSuchSetError() {
Response noSuchSet = given().get("/oai?verb=ListIdentifiers&set=census&metadataPrefix=dc");
noSuchSet.prettyPrint();
noSuchSet.then().assertThat()
.statusCode(OK.getStatusCode())
.body("oai.error.@code", equalTo("noRecordsMatch"))
.body("oai.error", equalTo("Requested set 'census' does not exist"));
}

// TODO:
// What else can we test?
// Some ideas:
Expand Down
Loading