fix: report history storage availability clearly

This commit is contained in:
lingniu
2026-06-29 14:35:13 +08:00
parent 2273d72e95
commit a66cfe1532
2 changed files with 56 additions and 0 deletions

View File

@@ -8,7 +8,9 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.io.IOException;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeParseException;
@@ -69,6 +71,18 @@ public final class ApiExceptionHandler {
return error(HttpStatus.BAD_REQUEST, "invalid date/time parameter: " + ex.getParsedString(), request);
}
@ExceptionHandler(NoResourceFoundException.class)
public ResponseEntity<ApiError> noResource(NoResourceFoundException ex,
HttpServletRequest request) {
return error(HttpStatus.NOT_FOUND, "resource not found: " + request.getRequestURI(), request);
}
@ExceptionHandler(IOException.class)
public ResponseEntity<ApiError> io(IOException ex,
HttpServletRequest request) {
return error(HttpStatus.SERVICE_UNAVAILABLE, safeMessage(ex, "history storage unavailable"), request);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiError> generic(Exception ex,
HttpServletRequest request) {

View File

@@ -3,14 +3,22 @@ package com.lingniu.ingest.eventhistory;
import com.lingniu.ingest.eventfilestore.EventFileStore;
import com.lingniu.ingest.eventfilestore.EventFileRecord;
import com.lingniu.ingest.protocol.gb32960.codec.Gb32960MessageDecoder;
import jakarta.servlet.http.HttpServletRequest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.http.HttpMethod;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -52,6 +60,32 @@ class ApiExceptionHandlerTest {
.andExpect(jsonPath("$.message").value("vin is required for gb32960 snapshots"));
}
@Test
void ioExceptionReturnsServiceUnavailable() throws Exception {
MockMvc mvc = standaloneSetup(new IoFailureController())
.setControllerAdvice(new ApiExceptionHandler())
.build();
mvc.perform(get("/io"))
.andExpect(status().isServiceUnavailable())
.andExpect(jsonPath("$.message").value("tdengine history query failed"))
.andExpect(jsonPath("$.path").value("/io"));
}
@Test
void noResourceReturnsNotFound() {
HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getRequestURI()).thenReturn("/missing");
var response = new ApiExceptionHandler().noResource(
new NoResourceFoundException(HttpMethod.GET, "/missing"),
request);
assertThat(response.getStatusCode().value()).isEqualTo(404);
assertThat(response.getBody()).isNotNull();
assertThat(response.getBody().message()).isEqualTo("resource not found: /missing");
}
private Gb32960DecodedFrameService service() {
EventFileStore store = new EventFileStore() {
@Override
@@ -69,4 +103,12 @@ class ApiExceptionHandlerTest {
archiveRoot,
null);
}
@RestController
private static final class IoFailureController {
@GetMapping("/io")
String io() throws IOException {
throw new IOException("tdengine history query failed");
}
}
}