Skip to content

Commit

Permalink
feat: rethrow notfound exception as badRequest on rpc calls (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaud-thorel-of authored Oct 8, 2024
1 parent ae69589 commit ce27b31
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import fr.ouestfrance.querydsl.postgrest.model.CountItem;
import fr.ouestfrance.querydsl.postgrest.model.HeaderRange;
import fr.ouestfrance.querydsl.postgrest.model.RangeResponse;
import fr.ouestfrance.querydsl.postgrest.model.exceptions.PostgrestRequestException;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import org.springframework.core.ParameterizedTypeReference;
Expand All @@ -13,6 +14,9 @@
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestClientResponseException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

Expand Down Expand Up @@ -99,8 +103,13 @@ public List<CountItem> count(String resource, Map<String, List<String>> map) {

@Override
public <V> V rpc(String rpcName, Map<String, List<String>> map, Object body, Type type) {
return (V) restTemplate.exchange(
getUri(rpcName, map), HttpMethod.POST, new HttpEntity<>(body, new HttpHeaders()), ParameterizedTypeReference.forType(type)).getBody();
try {
return (V) restTemplate.exchange(
getUri(rpcName, map), HttpMethod.POST, new HttpEntity<>(body, new HttpHeaders()), ParameterizedTypeReference.forType(type))
.getBody();
} catch (HttpClientErrorException.NotFound exception) {
throw new PostgrestRequestException(rpcName, exception.getMessage(), exception, exception.getResponseBodyAsString());
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import fr.ouestfrance.querydsl.postgrest.app.Post;
import fr.ouestfrance.querydsl.postgrest.app.PostRequestWithSelect;
import fr.ouestfrance.querydsl.postgrest.model.exceptions.PostgrestRequestException;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -16,6 +17,7 @@

import static fr.ouestfrance.querydsl.postgrest.TestUtils.jsonResponse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

@MockServerSettings(ports = 8007)
class PostgrestRpcTest {
Expand Down Expand Up @@ -72,4 +74,21 @@ void shouldCallRpcWithCriteriaResultIsList(MockServerClient client) {
assertNotNull(result);
System.out.println(result);
}


@Test
void shouldRaiseExceptionOn404(MockServerClient client) {
client.when(HttpRequest.request().withPath("/rpc/testV1"))
.respond(jsonResponse("""
{
"code":"PGRST202",
"details":"Searched for the function public_repository_depositaire.testV1 with parameters coordinates, type or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache.",
"hint":null,
"message":"Could not find the function public_repository_depositaire.testV1(coordinates, type) in the schema cache"
}
""").withStatusCode(404));
PostgrestRequestException exception = assertThrows(PostgrestRequestException.class, () -> rpcClient.executeRpc("testV1", Post.class));
assertNotNull(exception);
assertNotNull(exception.getResponseBody());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import fr.ouestfrance.querydsl.postgrest.model.CountItem;
import fr.ouestfrance.querydsl.postgrest.model.HeaderRange;
import fr.ouestfrance.querydsl.postgrest.model.RangeResponse;
import fr.ouestfrance.querydsl.postgrest.model.exceptions.PostgrestRequestException;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import org.springframework.core.ParameterizedTypeReference;
Expand All @@ -13,7 +14,10 @@
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import org.springframework.web.reactive.function.client.WebClientResponseException;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
Expand Down Expand Up @@ -93,14 +97,14 @@ public <V> V rpc(String rpcName, Map<String, List<String>> params, Object body,
uriBuilder.queryParams(toMultiMap(params));
return uriBuilder.build();
});
if(body != null){
request.bodyValue(body);
}
Optional.ofNullable(body).ifPresent(request::bodyValue);
Object result = request
.retrieve()
.bodyToMono(ParameterizedTypeReference.forType(clazz))
// On not found raise postgrestRequestException with body
.onErrorMap(WebClientResponseException.NotFound.class, e -> new PostgrestRequestException(rpcName, e.getMessage(), e, e.getResponseBodyAsString()))
.block();
if(result != null) {
if (result != null) {
return (V) result;
}
return null;
Expand Down Expand Up @@ -152,6 +156,7 @@ public <T> BulkResponse<T> delete(String resource, Map<String, List<String>> par

/**
* Convert map to MultiValueMap
*
* @param params map
* @return MultiValueMap
*/
Expand All @@ -161,7 +166,8 @@ private static MultiValueMap<String, String> toMultiMap(Map<String, List<String>

/**
* Safe add headers to httpHeaders
* @param headers headers
*
* @param headers headers
* @param httpHeaders httpHeaders
*/
private static void safeAdd(Map<String, List<String>> headers, HttpHeaders httpHeaders) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import fr.ouestfrance.querydsl.postgrest.app.Post;
import fr.ouestfrance.querydsl.postgrest.app.PostRequestWithSelect;
import fr.ouestfrance.querydsl.postgrest.model.exceptions.PostgrestRequestException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -15,6 +16,7 @@

import static fr.ouestfrance.querydsl.postgrest.TestUtils.jsonResponse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

@MockServerSettings(ports = 8007)
@Slf4j
Expand Down Expand Up @@ -70,4 +72,21 @@ void shouldCallRpcWithCriteriaResultIsList(MockServerClient client) {
assertNotNull(result);
}


@Test
void shouldRaiseExceptionOn404(MockServerClient client) {
client.when(HttpRequest.request().withPath("/rpc/testV1"))
.respond(jsonResponse("""
{
"code":"PGRST202",
"details":"Searched for the function public_repository_depositaire.testV1 with parameters coordinates, type or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache.",
"hint":null,
"message":"Could not find the function public_repository_depositaire.testV1(coordinates, type) in the schema cache"
}
""").withStatusCode(404));
PostgrestRequestException exception = assertThrows(PostgrestRequestException.class, () -> rpcClient.executeRpc("testV1", Post.class));
assertNotNull(exception);
assertNotNull(exception.getResponseBody());
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package fr.ouestfrance.querydsl.postgrest.model.exceptions;

import lombok.Getter;
import lombok.Setter;

/**
* Runtime exception for querying failure
*/
@Getter
@Setter
public class PostgrestRequestException extends RuntimeException {

private String responseBody;

/**
* PostgrestRequestException constructor
*
Expand All @@ -28,6 +35,19 @@ public PostgrestRequestException(String resourceName, String message, Throwable
this("Error on querying " + resourceName + " cause by " + message, cause);
}

/**
* PostgrestRequestException constructor
* @param resourceName resource name
* @param message cause message
* @param cause exception raised
* @param errorBody error body
*/
public PostgrestRequestException(String resourceName, String message, Throwable cause, String errorBody) {
this("Error on querying " + resourceName + " cause by " + message, cause);
this.responseBody = errorBody;
}


/**
* PostgrestRequestException constructor
*
Expand All @@ -46,4 +66,6 @@ public PostgrestRequestException(String message) {
public PostgrestRequestException(String message, Throwable cause) {
super(message, cause);
}


}

0 comments on commit ce27b31

Please sign in to comment.