fix: handle Dolibarr/PS 404 on empty filter results

Both APIs return 404 (not 200+empty) when a filter finds no results.
Catch DolibarrApiException(404) in getOrCreateThirdparty and
getProductByRef; catch PrestashopApiException(404) in
getProductByReference — treat as empty/not-found instead of error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
luklpz 2026-05-15 08:14:21 +02:00
parent fa20b7cc91
commit db4db1741d
2 changed files with 48 additions and 28 deletions

View File

@ -1,6 +1,7 @@
package com.teterialosjuanjos.tfg.sync_service.integration.dolibarr;
import com.teterialosjuanjos.tfg.sync_service.integration.dolibarr.dto.*;
import com.teterialosjuanjos.tfg.sync_service.integration.dolibarr.exception.DolibarrApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.ParameterizedTypeReference;
@ -50,15 +51,19 @@ public class DolibarrClient {
*/
public DolibarrProductDto getProductByRef(String ref) {
String filter = "(t.ref:=:'%s')".formatted(ref);
List<DolibarrProductDto> results = restClient.get()
.uri(u -> u.path("/products")
.queryParam("sqlfilters", filter)
.queryParam("limit", 1)
.build())
.retrieve()
.body(new ParameterizedTypeReference<List<DolibarrProductDto>>() {});
return (results != null && !results.isEmpty()) ? results.get(0) : null;
try {
List<DolibarrProductDto> results = restClient.get()
.uri(u -> u.path("/products")
.queryParam("sqlfilters", filter)
.queryParam("limit", 1)
.build())
.retrieve()
.body(new ParameterizedTypeReference<List<DolibarrProductDto>>() {});
return (results != null && !results.isEmpty()) ? results.get(0) : null;
} catch (DolibarrApiException e) {
if (e.getStatusCode().value() == 404) return null;
throw e;
}
}
/**
@ -119,13 +124,21 @@ public class DolibarrClient {
*/
public DolibarrThirdpartyDto getOrCreateThirdparty(String email, String name) {
log.debug("Looking up Dolibarr thirdparty email={}", email);
List<DolibarrThirdpartyDto> matches = restClient.get()
.uri(u -> u.path("/thirdparties")
.queryParam("sqlfilters", "(t.email:=:'%s')".formatted(email))
.queryParam("limit", 1)
.build())
.retrieve()
.body(new ParameterizedTypeReference<List<DolibarrThirdpartyDto>>() {});
List<DolibarrThirdpartyDto> matches = null;
try {
matches = restClient.get()
.uri(u -> u.path("/thirdparties")
.queryParam("sqlfilters", "(t.email:=:'%s')".formatted(email))
.queryParam("limit", 1)
.build())
.retrieve()
.body(new ParameterizedTypeReference<List<DolibarrThirdpartyDto>>() {});
} catch (DolibarrApiException e) {
// Dolibarr returns 404 (not 200 + empty array) when filter finds no results
if (e.getStatusCode().value() != 404) {
throw e;
}
}
if (matches != null && !matches.isEmpty()) {
return matches.get(0);

View File

@ -2,6 +2,7 @@ package com.teterialosjuanjos.tfg.sync_service.integration.prestashop;
import com.teterialosjuanjos.tfg.sync_service.config.IntegrationProperties;
import com.teterialosjuanjos.tfg.sync_service.integration.prestashop.dto.*;
import com.teterialosjuanjos.tfg.sync_service.integration.prestashop.exception.PrestashopApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
@ -66,20 +67,26 @@ public class PrestashopClient {
public Optional<PrestashopProductDto> getProductByReference(String reference) {
// PS WebService requires [value] brackets for exact-match filtering
String exactRef = "[" + reference + "]";
PrestashopProductDto.ListResponse response = restClient.get()
.uri(u -> u.path("/products")
.queryParam("ws_key", wsKey)
.queryParam("output_format", "JSON")
.queryParam("display", "full")
.queryParam("filter[reference]", exactRef)
.build())
.retrieve()
.body(PrestashopProductDto.ListResponse.class);
try {
PrestashopProductDto.ListResponse response = restClient.get()
.uri(u -> u.path("/products")
.queryParam("ws_key", wsKey)
.queryParam("output_format", "JSON")
.queryParam("display", "full")
.queryParam("filter[reference]", exactRef)
.build())
.retrieve()
.body(PrestashopProductDto.ListResponse.class);
if (response == null || response.products() == null || response.products().isEmpty()) {
return Optional.empty();
if (response == null || response.products() == null || response.products().isEmpty()) {
return Optional.empty();
}
return Optional.of(response.products().get(0));
} catch (PrestashopApiException e) {
// PS may return 404 instead of 200+empty when filter finds no results
if (e.getStatusCode() != null && e.getStatusCode().value() == 404) return Optional.empty();
throw e;
}
return Optional.of(response.products().get(0));
}
/**