fix: use byte[] for PS XML body; catch HttpMessageConversionException
ByteArrayHttpMessageConverter reliably handles application/xml content type via its */* support, avoiding potential StringHttpMessageConverter selection issues. Also add HttpMessageConversionException to per-item catches and widen outer infrastructure catch to RuntimeException, so any response-parsing failure is recorded in SyncLog.errorDetails instead of propagating as HTTP 500. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
121dc329f8
commit
997ed99895
|
|
@ -8,6 +8,7 @@ import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.client.RestClient;
|
import org.springframework.web.client.RestClient;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -97,7 +98,7 @@ public class PrestashopClient {
|
||||||
.queryParam("output_format", "JSON")
|
.queryParam("output_format", "JSON")
|
||||||
.build())
|
.build())
|
||||||
.contentType(MediaType.APPLICATION_XML)
|
.contentType(MediaType.APPLICATION_XML)
|
||||||
.body(toProductXml(dto))
|
.body(toProductXml(dto).getBytes(StandardCharsets.UTF_8))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.body(PrestashopProductDto.SingleResponse.class);
|
.body(PrestashopProductDto.SingleResponse.class);
|
||||||
|
|
||||||
|
|
@ -113,7 +114,7 @@ public class PrestashopClient {
|
||||||
.queryParam("output_format", "JSON")
|
.queryParam("output_format", "JSON")
|
||||||
.build(id))
|
.build(id))
|
||||||
.contentType(MediaType.APPLICATION_XML)
|
.contentType(MediaType.APPLICATION_XML)
|
||||||
.body(toProductXml(dto))
|
.body(toProductXml(dto).getBytes(StandardCharsets.UTF_8))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.toBodilessEntity();
|
.toBodilessEntity();
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +153,7 @@ public class PrestashopClient {
|
||||||
.queryParam("output_format", "JSON")
|
.queryParam("output_format", "JSON")
|
||||||
.build(id))
|
.build(id))
|
||||||
.contentType(MediaType.APPLICATION_XML)
|
.contentType(MediaType.APPLICATION_XML)
|
||||||
.body(toStockAvailableXml(dto))
|
.body(toStockAvailableXml(dto).getBytes(StandardCharsets.UTF_8))
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.toBodilessEntity();
|
.toBodilessEntity();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import com.teterialosjuanjos.tfg.sync_service.integration.prestashop.exception.P
|
||||||
import com.teterialosjuanjos.tfg.sync_service.mapping.*;
|
import com.teterialosjuanjos.tfg.sync_service.mapping.*;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.converter.HttpMessageConversionException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestClientException;
|
import org.springframework.web.client.RestClientException;
|
||||||
|
|
||||||
|
|
@ -84,14 +85,15 @@ public class OrderSyncService {
|
||||||
try {
|
try {
|
||||||
importOrder(psOrder);
|
importOrder(psOrder);
|
||||||
processed++;
|
processed++;
|
||||||
} catch (DolibarrApiException | PrestashopApiException | RestClientException e) {
|
} catch (DolibarrApiException | PrestashopApiException
|
||||||
|
| RestClientException | HttpMessageConversionException e) {
|
||||||
failed++;
|
failed++;
|
||||||
String msg = "PS order %d: %s".formatted(psOrder.id(), e.getMessage());
|
String msg = "PS order %d: %s".formatted(psOrder.id(), e.getMessage());
|
||||||
errors.add(msg);
|
errors.add(msg);
|
||||||
log.warn("OrderSync item failed: {}", msg);
|
log.warn("OrderSync item failed: {}", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RestClientException e) {
|
} catch (RuntimeException e) {
|
||||||
failed++;
|
failed++;
|
||||||
String msg = "Failed to fetch orders from PrestaShop: " + e.getMessage();
|
String msg = "Failed to fetch orders from PrestaShop: " + e.getMessage();
|
||||||
errors.add(msg);
|
errors.add(msg);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import com.teterialosjuanjos.tfg.sync_service.integration.prestashop.exception.P
|
||||||
import com.teterialosjuanjos.tfg.sync_service.mapping.*;
|
import com.teterialosjuanjos.tfg.sync_service.mapping.*;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.converter.HttpMessageConversionException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestClientException;
|
import org.springframework.web.client.RestClientException;
|
||||||
|
|
||||||
|
|
@ -69,7 +70,8 @@ public class ProductSyncService {
|
||||||
try {
|
try {
|
||||||
pushProduct(product);
|
pushProduct(product);
|
||||||
processed++;
|
processed++;
|
||||||
} catch (DolibarrApiException | PrestashopApiException | RestClientException e) {
|
} catch (DolibarrApiException | PrestashopApiException
|
||||||
|
| RestClientException | HttpMessageConversionException e) {
|
||||||
failed++;
|
failed++;
|
||||||
String msg = "SKU %s: %s".formatted(product.ref(), e.getMessage());
|
String msg = "SKU %s: %s".formatted(product.ref(), e.getMessage());
|
||||||
errors.add(msg);
|
errors.add(msg);
|
||||||
|
|
@ -77,7 +79,7 @@ public class ProductSyncService {
|
||||||
markError(product.ref(), e.getMessage());
|
markError(product.ref(), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RestClientException e) {
|
} catch (RuntimeException e) {
|
||||||
failed++;
|
failed++;
|
||||||
String msg = "Failed to fetch products from Dolibarr: " + e.getMessage();
|
String msg = "Failed to fetch products from Dolibarr: " + e.getMessage();
|
||||||
errors.add(msg);
|
errors.add(msg);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import com.teterialosjuanjos.tfg.sync_service.integration.prestashop.exception.P
|
||||||
import com.teterialosjuanjos.tfg.sync_service.mapping.*;
|
import com.teterialosjuanjos.tfg.sync_service.mapping.*;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.converter.HttpMessageConversionException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.client.RestClientException;
|
import org.springframework.web.client.RestClientException;
|
||||||
|
|
||||||
|
|
@ -56,14 +57,15 @@ public class StockSyncService {
|
||||||
if (pushStock(mapping)) {
|
if (pushStock(mapping)) {
|
||||||
processed++;
|
processed++;
|
||||||
}
|
}
|
||||||
} catch (DolibarrApiException | PrestashopApiException | RestClientException e) {
|
} catch (DolibarrApiException | PrestashopApiException
|
||||||
|
| RestClientException | HttpMessageConversionException e) {
|
||||||
failed++;
|
failed++;
|
||||||
String msg = "SKU %s: %s".formatted(mapping.getSku(), e.getMessage());
|
String msg = "SKU %s: %s".formatted(mapping.getSku(), e.getMessage());
|
||||||
errors.add(msg);
|
errors.add(msg);
|
||||||
log.warn("StockSync item failed: {}", msg);
|
log.warn("StockSync item failed: {}", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (RestClientException e) {
|
} catch (RuntimeException e) {
|
||||||
failed++;
|
failed++;
|
||||||
String msg = "Infrastructure error: " + e.getMessage();
|
String msg = "Infrastructure error: " + e.getMessage();
|
||||||
errors.add(msg);
|
errors.add(msg);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue