Skip to content

Commit 38d9959

Browse files
authored
SAK-51207 Entitybroker improve exception handling by logging original exception (#13505)
1 parent c212187 commit 38d9959

File tree

2 files changed

+46
-19
lines changed

2 files changed

+46
-19
lines changed

entitybroker/api/src/java/org/sakaiproject/entitybroker/exception/EntityException.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,20 @@ public EntityException(String message, String entityReference, int responseCode)
9494
this.responseCode = responseCode;
9595
}
9696

97+
/**
98+
* Create an exception to indicate that this entity could not found,
99+
* this will trigger an HTTP error related to the responseCode if not caught before reaching the direct servlet
100+
*
101+
* @param message a message explaining the failure
102+
* @param entityReference the unique reference to an entity
103+
* @param responseCode the response code related to the failure that occurred,
104+
* should match with the SC constants in {@link HttpServletResponse}
105+
* @param cause the underlying cause of this exception
106+
*/
107+
public EntityException(String message, String entityReference, int responseCode, Throwable cause) {
108+
// Assuming EntityBrokerException has a constructor that takes (message, reference, cause)
109+
super(message, entityReference, cause);
110+
this.responseCode = responseCode;
111+
}
112+
97113
}

entitybroker/rest/src/java/org/sakaiproject/entitybroker/rest/EntityActionsManager.java

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -212,27 +212,38 @@ public ActionReturn handleCustomActionExecution(ActionsExecutable actionProvider
212212
} catch (IllegalAccessException e) {
213213
throw new RuntimeException("Fatal error trying to execute custom action method: " + customAction, e);
214214
} catch (InvocationTargetException e) {
215-
if (e.getCause() != null) {
216-
if (e.getCause().getClass().isAssignableFrom(IllegalArgumentException.class)) {
217-
throw new IllegalArgumentException(e.getCause().getMessage() + " (rethrown)", e.getCause());
218-
} else if (e.getCause().getClass().isAssignableFrom(EntityNotFoundException.class)) {
219-
throw new EntityNotFoundException(e.getCause().getMessage() + " (rethrown)", ref+"", e.getCause());
220-
} else if (e.getCause().getClass().isAssignableFrom(FormatUnsupportedException.class)) {
221-
String format = ((FormatUnsupportedException)e.getCause()).format;
222-
throw new FormatUnsupportedException(e.getCause().getMessage() + " (rethrown)", e.getCause(), ref+"", format);
223-
} else if (e.getCause().getClass().isAssignableFrom(UnsupportedOperationException.class)) {
224-
throw new UnsupportedOperationException(e.getCause().getMessage() + " (rethrown)", e.getCause());
225-
} else if (e.getCause().getClass().isAssignableFrom(EntityException.class)) {
226-
int code = ((EntityException)e.getCause()).responseCode;
227-
throw new EntityException(e.getCause().getMessage() + " (rethrown)", ref+"", code);
228-
} else if (e.getCause().getClass().isAssignableFrom(IllegalStateException.class)) {
229-
throw new IllegalStateException(e.getCause().getMessage() + " (rethrown)", e.getCause());
230-
} else if (e.getCause().getClass().isAssignableFrom(SecurityException.class)) {
231-
throw new SecurityException(e.getCause().getMessage() + " (rethrown)", e.getCause());
215+
Throwable cause = e.getCause(); // Get the real cause once
216+
217+
if (cause != null) {
218+
if (cause instanceof IllegalArgumentException) {
219+
throw new IllegalArgumentException(cause.getMessage() + " (rethrown)", cause);
220+
} else if (cause instanceof EntityNotFoundException) {
221+
throw new EntityNotFoundException(cause.getMessage() + " (rethrown)", ref + "", cause);
222+
} else if (cause instanceof FormatUnsupportedException) {
223+
FormatUnsupportedException fue = (FormatUnsupportedException) cause;
224+
throw new FormatUnsupportedException(cause.getMessage() + " (rethrown)", cause, ref + "", fue.format);
225+
} else if (cause instanceof UnsupportedOperationException) {
226+
throw new UnsupportedOperationException(cause.getMessage() + " (rethrown)", cause);
227+
} else if (cause instanceof EntityException) {
228+
EntityException ee = (EntityException) cause;
229+
throw new EntityException(cause.getMessage() + " (rethrown)", ref + "", ee.responseCode, cause);
230+
} else if (cause instanceof IllegalStateException) {
231+
throw new IllegalStateException(cause.getMessage() + " (rethrown)", cause);
232+
} else if (cause instanceof SecurityException) {
233+
throw new SecurityException(cause.getMessage() + " (rethrown)", cause);
234+
} else {
235+
// Log the UNHANDLED cause WITH its stack trace
236+
log.error("Unhandled target exception type [{}], rethrowing as a RuntimeException. Original cause:",
237+
cause.getClass().getName(), cause);
238+
// Rethrowing a generic wrapper, preserving the actual cause
239+
throw new RuntimeException("Unhandled exception during custom action execution: " + customAction, cause);
232240
}
233-
log.error("Target exception class not identified, rethrowing as a RuntimeException: {}", e.getCause().toString());
241+
} else {
242+
// InvocationTargetException happened, but getCause() is null. Less common.
243+
// Wrap the InvocationTargetException itself.
244+
log.error("InvocationTargetException occurred with no cause during custom action execution: {}", customAction, e);
245+
throw new RuntimeException("Fatal error trying to execute custom action method (no specific cause): " + customAction, e);
234246
}
235-
throw new RuntimeException("Fatal error trying to execute custom action method: " + customAction, e);
236247
}
237248
}
238249
if (result != null) {

0 commit comments

Comments
 (0)