2222
2323import com .inrupt .client .*;
2424import com .inrupt .client .auth .Session ;
25+ import com .inrupt .client .spi .JsonService ;
26+ import com .inrupt .client .spi .ServiceProvider ;
2527
2628import java .io .ByteArrayInputStream ;
2729import java .io .IOException ;
@@ -52,11 +54,22 @@ public class SolidClient {
5254 private final Client client ;
5355 private final Headers defaultHeaders ;
5456 private final boolean fetchAfterWrite ;
57+ private JsonService jsonService ;
5558
5659 SolidClient (final Client client , final Headers headers , final boolean fetchAfterWrite ) {
5760 this .client = Objects .requireNonNull (client , "Client may not be null!" );
5861 this .defaultHeaders = Objects .requireNonNull (headers , "Headers may not be null!" );
5962 this .fetchAfterWrite = fetchAfterWrite ;
63+
64+ // It is acceptable for a SolidClient instance to be in a classpath without any implementation for
65+ // JsonService, in which case the ProblemDetails exceptions will fallback to default and not be parsed.
66+ JsonService js ;
67+ try {
68+ js = ServiceProvider .getJsonService ();
69+ } catch (IllegalStateException e ) {
70+ js = null ;
71+ }
72+ this .jsonService = js ;
6073 }
6174
6275 /**
@@ -122,12 +135,18 @@ public <T extends Resource> CompletionStage<T> read(final URI identifier, final
122135 return client .send (request , Response .BodyHandlers .ofByteArray ())
123136 .thenApply (response -> {
124137 if (response .statusCode () >= ERROR_STATUS ) {
125- throw SolidClientException .fromErrorResponse (
138+ final ProblemDetails pd = ProblemDetails .fromErrorResponse (
139+ response .statusCode (),
140+ response .headers (),
141+ response .body (),
142+ this .jsonService
143+ );
144+ throw SolidClientException .handle (
126145 "Unable to read resource at " + request .uri (),
146+ pd ,
127147 response .uri (),
128- response .statusCode (),
129148 response .headers (),
130- response .body ()
149+ new String ( response .body () )
131150 );
132151 } else {
133152 final String contentType = response .headers ().firstValue (CONTENT_TYPE )
@@ -277,12 +296,18 @@ public <T extends Resource> CompletionStage<Void> delete(final T resource, final
277296 if (isSuccess (res .statusCode ())) {
278297 return null ;
279298 } else {
280- throw SolidClientException .fromErrorResponse (
281- "Unable to delete resource" ,
282- resource .getIdentifier (),
283- res .statusCode (),
284- res .headers (),
285- res .body ()
299+ final ProblemDetails pd = ProblemDetails .fromErrorResponse (
300+ res .statusCode (),
301+ res .headers (),
302+ res .body (),
303+ this .jsonService
304+ );
305+ throw SolidClientException .handle (
306+ "Unable to delete resource" ,
307+ pd ,
308+ resource .getIdentifier (),
309+ res .headers (),
310+ new String (res .body ())
286311 );
287312 }
288313 });
@@ -369,12 +394,18 @@ <T extends Resource> Function<Response<byte[]>, CompletionStage<T>> handleRespon
369394 final Headers headers , final String message ) {
370395 return res -> {
371396 if (!isSuccess (res .statusCode ())) {
372- throw SolidClientException .fromErrorResponse (
373- message ,
374- resource .getIdentifier (),
375- res .statusCode (),
376- res .headers (),
377- res .body ()
397+ final ProblemDetails pd = ProblemDetails .fromErrorResponse (
398+ res .statusCode (),
399+ res .headers (),
400+ res .body (),
401+ this .jsonService
402+ );
403+ throw SolidClientException .handle (
404+ message ,
405+ pd ,
406+ resource .getIdentifier (),
407+ res .headers (),
408+ new String (res .body ())
378409 );
379410 }
380411
@@ -385,7 +416,6 @@ <T extends Resource> Function<Response<byte[]>, CompletionStage<T>> handleRespon
385416 @ SuppressWarnings ("unchecked" )
386417 final Class <T > clazz = (Class <T >) resource .getClass ();
387418 return read (resource .getIdentifier (), headers , clazz );
388-
389419 };
390420 }
391421
0 commit comments