Skip to content

Commit ab97878

Browse files
Merge branch 'develop' into 12030-unable-to-delete-dataverse-with-metrics
2 parents fc3b388 + 96e96f4 commit ab97878

File tree

5 files changed

+78
-41
lines changed

5 files changed

+78
-41
lines changed

.github/workflows/pr_comment_commands.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
steps:
1111
- name: Dispatch
12-
uses: peter-evans/slash-command-dispatch@v4
12+
uses: peter-evans/slash-command-dispatch@v5
1313
with:
1414
# This token belongs to @dataversebot and has sufficient scope.
1515
token: ${{ secrets.GHCR_TOKEN }}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package edu.harvard.iq.dataverse.api.errorhandlers;
2+
3+
import edu.harvard.iq.dataverse.api.util.JsonResponseBuilder;
4+
import edu.harvard.iq.dataverse.util.json.JsonParseException;
5+
import jakarta.json.stream.JsonParsingException;
6+
import jakarta.servlet.http.HttpServletRequest;
7+
import jakarta.ws.rs.core.Context;
8+
import jakarta.ws.rs.core.Response;
9+
import jakarta.ws.rs.ext.ExceptionMapper;
10+
import jakarta.ws.rs.ext.Provider;
11+
12+
import java.util.logging.Level;
13+
import java.util.logging.Logger;
14+
15+
/**
16+
* Make a failing JSON parsing request appear to be a BadRequest (error code 400)
17+
* and send a message what just failed...
18+
*/
19+
public abstract class JsonExceptionsHandler<T extends Exception> implements ExceptionMapper<T>{
20+
21+
static final Logger logger = Logger.getLogger(JsonExceptionsHandler.class.getSimpleName());
22+
23+
@Context
24+
HttpServletRequest request;
25+
26+
@Override
27+
public Response toResponse(T ex) {
28+
return JsonResponseBuilder.error(Response.Status.BAD_REQUEST)
29+
.log(logger, Level.FINER)
30+
.message(ex.getMessage())
31+
.build();
32+
}
33+
34+
/**
35+
* Handler for jakarta.json.stream.JsonParsingException
36+
*/
37+
@Provider
38+
public static class JsonParsingExceptionMapper extends JsonExceptionsHandler<JsonParsingException> {
39+
}
40+
41+
/**
42+
* Handler for jakarta.json.stream.JsonParsingException
43+
*/
44+
@Provider
45+
public static class DvUtilJsonParseExceptionMapper extends JsonExceptionsHandler<JsonParseException> {
46+
}
47+
48+
// Add more handlers as needed (e.g., for Jackson, GSON, etc.)
49+
// @Provider
50+
// public static class JsonProcessingExceptionMapper extends JsonExceptionHandler<JsonProcessingException> {
51+
// }
52+
}

src/main/java/edu/harvard/iq/dataverse/api/errorhandlers/JsonParseExceptionHandler.java

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/main/java/edu/harvard/iq/dataverse/api/util/JsonResponseBuilder.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package edu.harvard.iq.dataverse.api.util;
22

33
import jakarta.json.Json;
4+
import jakarta.json.JsonObject;
45
import jakarta.json.JsonValue;
56
import jakarta.json.JsonObjectBuilder;
67
import jakarta.servlet.ServletResponse;
@@ -143,8 +144,9 @@ public JsonResponseBuilder internalError(Throwable ex) {
143144
* @return JAX-RS response including JSON message
144145
*/
145146
public Response build() {
147+
JsonObject entity = entityBuilder.build();
146148
return jerseyResponseBuilder.type(MediaType.APPLICATION_JSON_TYPE)
147-
.entity(this.entityBuilder.build())
149+
.entity(entity)
148150
.build();
149151
}
150152

@@ -215,9 +217,14 @@ public JsonResponseBuilder log(Logger logger, Level level, Optional<Throwable> e
215217
if ( ! logger.isLoggable(level) || alreadyLogged )
216218
return this;
217219

218-
StringBuilder metadata = new StringBuilder("");
219-
this.entityBuilder.build()
220-
.forEach((k,v) -> metadata.append("_"+k+"="+v.toString()+";"));
220+
// This is necessary because we need to build in two places: logging and response creation.
221+
// Without cloning the object builder, we'd end up with an empty entity in the response when logging before that.
222+
JsonObject entity = this.entityBuilder.build();
223+
this.entityBuilder = Json.createObjectBuilder(entity);
224+
225+
StringBuilder metadata = new StringBuilder();
226+
entity.forEach((k,v) -> metadata.append("_").append(k).append("=").append(v.toString()).append(";"));
227+
221228
// remove trailing ;
222229
metadata.deleteCharAt(metadata.length()-1);
223230

src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import org.junit.jupiter.api.Test;
2020
import org.junit.jupiter.params.ParameterizedTest;
2121
import org.junit.jupiter.params.provider.ValueSource;
22-
2322
import java.io.IOException;
2423
import java.nio.file.Files;
2524
import java.nio.file.Paths;
@@ -29,7 +28,6 @@
2928
import java.util.Map;
3029
import java.util.UUID;
3130
import java.util.logging.Logger;
32-
3331
import static io.restassured.RestAssured.given;
3432
import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
3533
import static jakarta.ws.rs.core.Response.Status.CREATED;
@@ -43,6 +41,7 @@
4341
import static org.hamcrest.CoreMatchers.notNullValue;
4442
import static org.junit.jupiter.api.Assertions.assertEquals;
4543
import static org.junit.jupiter.api.Assertions.assertFalse;
44+
import io.restassured.http.ContentType;
4645
import static org.junit.jupiter.api.Assertions.assertTrue;
4746

4847
public class AdminIT {
@@ -681,6 +680,19 @@ public void testCreateNonBuiltinUserViaApi() {
681680
assertEquals(200, deleteUserToConvert.getStatusCode());
682681
}
683682

683+
684+
@Test
685+
void testCreateUserViaAPI_WithInvalidJson() {
686+
Response response = given()
687+
.body("{invalid}")
688+
.contentType(ContentType.JSON)
689+
.post("/api/admin/authenticatedUsers");
690+
691+
response.then()
692+
.assertThat()
693+
.statusCode(BAD_REQUEST.getStatusCode())
694+
.body("message", containsString("Unexpected char"));
695+
}
684696

685697

686698
@Test

0 commit comments

Comments
 (0)