Rev 36321 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package com.spice.profitmandi.web.v2.controller;import com.spice.profitmandi.common.model.ProfitMandiResponse;import com.spice.profitmandi.common.model.ResponseStatus;import com.spice.profitmandi.web.v2.response.ApiResponse;import com.spice.profitmandi.web.v2.response.ErrorDetail;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;public abstract class V2BaseController {/*** Bridges a v1 controller's ResponseEntity into the v2 ApiResponse envelope.** Fix for silent-success bug: v1 code often signals validation failure by* returning {@code responseSender.badRequest(payload)} — a 4xx response* whose body carries context (e.g. cart with price-changed messages from* {@code OrderController.createOrder}). The previous version blindly wrapped* everything as {@code ApiResponse.success} + 200, so the React client* treated a rejected order as a placed order and navigated to "Order* Placed!" while no transaction was written. We now preserve the v1 status* so axios rejects and the caller's catch-block runs.*/@SuppressWarnings("rawtypes")protected ResponseEntity<ApiResponse<?>> wrapResponse(ResponseEntity<?> v1Response) {Object body = v1Response.getBody();Object data = body;boolean v1FailureFlag = false;if (body instanceof ProfitMandiResponse) {ProfitMandiResponse pmr = (ProfitMandiResponse) body;data = pmr.getResponse();v1FailureFlag = pmr.getResponseStatus() == ResponseStatus.FAILURE;}HttpStatus status = v1Response.getStatusCode();boolean httpError = status != null && status.value() >= 400;if (httpError || v1FailureFlag) {HttpStatus errorStatus = httpError ? status : HttpStatus.BAD_REQUEST;String message = extractMessage(data, errorStatus);ErrorDetail detail = new ErrorDetail();detail.setType("V1BadRequest");detail.setMessage(message);@SuppressWarnings({"unchecked", "rawtypes"})ApiResponse errorResponse = ApiResponse.error(errorStatus.value(), message, detail);// Preserve v1's original payload so the client can still surface// context (e.g. price-changed cart messages) if it wants to.errorResponse.setData(data);return ResponseEntity.status(errorStatus).body(errorResponse);}ApiResponse<?> apiResponse = ApiResponse.success(data);return ResponseEntity.ok(apiResponse);}private String extractMessage(Object data, HttpStatus fallbackStatus) {if (data == null) return fallbackStatus.getReasonPhrase();try {java.lang.reflect.Method m = data.getClass().getMethod("getCartMessages");Object messages = m.invoke(data);if (messages instanceof java.util.List && !((java.util.List<?>) messages).isEmpty()) {Object first = ((java.util.List<?>) messages).get(0);java.lang.reflect.Method textMethod = first.getClass().getMethod("getMessageText");Object text = textMethod.invoke(first);if (text != null && !text.toString().isEmpty()) return text.toString();}} catch (Exception ignore) {// fall through to generic message}try {java.lang.reflect.Method m = data.getClass().getMethod("getMessage");Object text = m.invoke(data);if (text != null && !text.toString().isEmpty()) return text.toString();} catch (Exception ignore) {// fall through}return fallbackStatus.getReasonPhrase();}}