fix(appointment): retain safe synchronization failure diagnostics
This commit is contained in:
+14
-1
@@ -21,7 +21,20 @@ public class AppointmentWorkSynchronizationJob {
|
||||
cursor=result.complete()?null:result.nextCursor();
|
||||
} catch(RuntimeException error) {
|
||||
cursor=null;
|
||||
log.warn("Appointment work synchronization incomplete; next scan restarts from first page: {}",error.getClass().getSimpleName());
|
||||
log.warn("Appointment work synchronization incomplete; next scan restarts from first page: {}",failureDiagnostic(error));
|
||||
}
|
||||
}
|
||||
/** Keep causes and code locations, never exception messages that may contain remote payloads or credentials. */
|
||||
static String failureDiagnostic(Throwable error) {
|
||||
var causes=new java.util.ArrayList<String>();
|
||||
var seen=java.util.Collections.newSetFromMap(new java.util.IdentityHashMap<Throwable,Boolean>());
|
||||
for(var current=error;current!=null && causes.size()<6 && seen.add(current);current=current.getCause()) {
|
||||
String status=current instanceof org.springframework.web.server.ResponseStatusException response?"["+response.getStatusCode().value()+"]":"";
|
||||
String location=java.util.Arrays.stream(current.getStackTrace())
|
||||
.filter(frame->frame.getClassName().startsWith("com.baiyue.") && !frame.getClassName().equals(AppointmentWorkPolicy.class.getName()))
|
||||
.findFirst().map(frame->"@"+frame.getClassName()+":"+frame.getLineNumber()).orElse("");
|
||||
causes.add(current.getClass().getSimpleName()+status+location);
|
||||
}
|
||||
return String.join(" <- ",causes);
|
||||
}
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baiyue.lastleg.appointmentwork;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class AppointmentWorkSynchronizationJobTest {
|
||||
@Test void diagnosticKeepsCauseAndCodeWithoutRemoteMessages() {
|
||||
var cause=new IllegalArgumentException("Authorization: Bearer secret; private remote body");
|
||||
var error=new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE,"private response",cause);
|
||||
assertThat(AppointmentWorkSynchronizationJob.failureDiagnostic(error))
|
||||
.contains("ResponseStatusException[503]", "IllegalArgumentException", "AppointmentWorkSynchronizationJobTest:")
|
||||
.doesNotContain("secret", "private", "Authorization", "Bearer");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user