You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2014/12/09 00:47:39 UTC
[8/9] isis git commit: ISIS-966: exceptions in RO viewer should be
serialized as JSON, not HTML.
ISIS-966: exceptions in RO viewer should be serialized as JSON, not HTML.
Also: better support for "causedBy", and include the className also in the JSON.
Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/807c6ccf
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/807c6ccf
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/807c6ccf
Branch: refs/heads/master
Commit: 807c6ccf9944f34a6e91282b99c3b781574d1be1
Parents: 30b8f01
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Mon Dec 8 20:23:35 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Mon Dec 8 23:22:36 2014 +0000
----------------------------------------------------------------------
.../transaction/IsisTransactionManager.java | 2 +-
...estfulObjectsApplicationExceptionMapper.java | 65 +-------------
.../RestfulObjectsApplicationExceptionPojo.java | 88 +++++++++++++++++++
.../server/RuntimeExceptionMapper.java | 67 +++------------
.../server/RuntimeExceptionPojo.java | 89 ++++++++++++++++++++
5 files changed, 193 insertions(+), 118 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/isis/blob/807c6ccf/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java
index b36e330..bdb56e8 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransactionManager.java
@@ -213,7 +213,7 @@ public class IsisTransactionManager implements SessionScopedComponent {
if (!initiallyInTransaction) {
abortTransaction();
} else {
- // ensure that this xactn cannot be committed
+ // ensure that this xactn cannot be committed (sets state to MUST_ABORT), and capture the cause so can be rendered appropriately by some higher level in the call stack
getTransaction().setAbortCause(new IsisException(ex));
}
throw ex;
http://git-wip-us.apache.org/repos/asf/isis/blob/807c6ccf/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java
index 4236704..92049ae 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionMapper.java
@@ -18,22 +18,17 @@
*/
package org.apache.isis.viewer.restfulobjects.server;
-import java.util.List;
-
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
-import com.google.common.collect.Lists;
-
import org.apache.isis.core.commons.exceptions.ExceptionUtils;
import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
import org.apache.isis.viewer.restfulobjects.applib.util.JsonMapper;
-import org.apache.isis.viewer.restfulobjects.rendering.HasHttpStatusCode;
import org.apache.isis.viewer.restfulobjects.rendering.RestfulObjectsApplicationException;
//@Path("/") // FIXME: workaround for TomEE ... but breaks the RestEasy TCK tests so commented out:-(
@@ -56,7 +51,7 @@ public class RestfulObjectsApplicationExceptionMapper implements ExceptionMapper
} else {
String body;
try {
- body = JsonMapper.instance().write(ExceptionPojo.create(cause));
+ body = JsonMapper.instance().write(RestfulObjectsApplicationExceptionPojo.create(cause));
} catch (final Exception e) {
// fallback
body = "{ \"exception\": \"" + ExceptionUtils.getFullStackTrace(cause) + "\" }";
@@ -72,63 +67,5 @@ public class RestfulObjectsApplicationExceptionMapper implements ExceptionMapper
return builder.build();
}
- private static class ExceptionPojo {
-
- public static ExceptionPojo create(final Throwable ex) {
- return new ExceptionPojo(ex);
- }
-
- private static String format(final StackTraceElement stackTraceElement) {
- return stackTraceElement.toString();
- }
-
- private final int httpStatusCode;
- private final String message;
- private final List<String> stackTrace = Lists.newArrayList();
- private ExceptionPojo causedBy;
-
- public ExceptionPojo(final Throwable ex) {
- httpStatusCode = getHttpStatusCodeIfAny(ex);
- this.message = ex.getMessage();
- final StackTraceElement[] stackTraceElements = ex.getStackTrace();
- for (final StackTraceElement stackTraceElement : stackTraceElements) {
- this.stackTrace.add(format(stackTraceElement));
- }
- final Throwable cause = ex.getCause();
- if (cause != null && cause != ex) {
- this.causedBy = new ExceptionPojo(cause);
- }
- }
-
- private int getHttpStatusCodeIfAny(final Throwable ex) {
- if (!(ex instanceof HasHttpStatusCode)) {
- return 0;
- }
- final HasHttpStatusCode hasHttpStatusCode = (HasHttpStatusCode) ex;
- return hasHttpStatusCode.getHttpStatusCode().getStatusCode();
- }
-
- @SuppressWarnings("unused")
- public int getHttpStatusCode() {
- return httpStatusCode;
- }
-
- @SuppressWarnings("unused")
- public String getMessage() {
- return message;
- }
-
- @SuppressWarnings("unused")
- public List<String> getStackTrace() {
- return stackTrace;
- }
-
- @SuppressWarnings("unused")
- public ExceptionPojo getCausedBy() {
- return causedBy;
- }
-
- }
-
}
http://git-wip-us.apache.org/repos/asf/isis/blob/807c6ccf/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionPojo.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionPojo.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionPojo.java
new file mode 100644
index 0000000..194344e
--- /dev/null
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RestfulObjectsApplicationExceptionPojo.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.viewer.restfulobjects.server;
+
+import java.util.List;
+import com.google.common.collect.Lists;
+import org.apache.isis.viewer.restfulobjects.rendering.HasHttpStatusCode;
+
+class RestfulObjectsApplicationExceptionPojo {
+
+ public static RestfulObjectsApplicationExceptionPojo create(final Throwable ex) {
+ return new RestfulObjectsApplicationExceptionPojo(ex);
+ }
+
+ private static String format(final StackTraceElement stackTraceElement) {
+ return stackTraceElement.toString();
+ }
+
+ private final String className;
+ private final int httpStatusCode;
+ private final String message;
+ private final List<String> stackTrace = Lists.newArrayList();
+ private RestfulObjectsApplicationExceptionPojo causedBy;
+
+ public RestfulObjectsApplicationExceptionPojo(final Throwable ex) {
+ this.className = ex.getClass().getName();
+ this.httpStatusCode = getHttpStatusCodeIfAny(ex);
+ this.message = ex.getMessage();
+ final StackTraceElement[] stackTraceElements = ex.getStackTrace();
+ for (final StackTraceElement stackTraceElement : stackTraceElements) {
+ this.stackTrace.add(format(stackTraceElement));
+ }
+ final Throwable cause = ex.getCause();
+ if (cause != null && cause != ex) {
+ this.causedBy = new RestfulObjectsApplicationExceptionPojo(cause);
+ }
+ }
+
+ private int getHttpStatusCodeIfAny(final Throwable ex) {
+ if (!(ex instanceof HasHttpStatusCode)) {
+ return 0;
+ }
+ final HasHttpStatusCode hasHttpStatusCode = (HasHttpStatusCode) ex;
+ return hasHttpStatusCode.getHttpStatusCode().getStatusCode();
+ }
+
+ @SuppressWarnings("unused")
+ public String getClassName() {
+ return className;
+ }
+
+ @SuppressWarnings("unused")
+ public int getHttpStatusCode() {
+ return httpStatusCode;
+ }
+
+ @SuppressWarnings("unused")
+ public String getMessage() {
+ return message;
+ }
+
+ @SuppressWarnings("unused")
+ public List<String> getStackTrace() {
+ return stackTrace;
+ }
+
+ @SuppressWarnings("unused")
+ public RestfulObjectsApplicationExceptionPojo getCausedBy() {
+ return causedBy;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/807c6ccf/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionMapper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionMapper.java
index 315451c..9e3f062 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionMapper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionMapper.java
@@ -19,17 +19,15 @@
package org.apache.isis.viewer.restfulobjects.server;
import java.util.List;
-
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
-
-import com.google.common.collect.Lists;
-
+import com.google.common.base.Throwables;
import org.jboss.resteasy.spi.Failure;
-
import org.apache.isis.core.commons.exceptions.ExceptionUtils;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
import org.apache.isis.viewer.restfulobjects.applib.RestfulMediaType;
import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse.HttpStatusCode;
import org.apache.isis.viewer.restfulobjects.applib.util.JsonMapper;
@@ -39,6 +37,16 @@ public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException>
@Override
public Response toResponse(final RuntimeException ex) {
+ // since have rendered...
+ final IsisTransaction currentTransaction = IsisContext.getTransactionManager().getTransaction();
+
+ final Throwable rootCause = Throwables.getRootCause(ex);
+ final List<Throwable> causalChain = Throwables.getCausalChain(ex);
+ for (Throwable throwable : causalChain) {
+ if(throwable == rootCause) {
+ currentTransaction.clearAbortCause();
+ }
+ }
HttpStatusCode statusCode = HttpStatusCode.INTERNAL_SERVER_ERROR;
if(ex instanceof Failure) {
Failure failure = (Failure) ex;
@@ -48,56 +56,9 @@ public class RuntimeExceptionMapper implements ExceptionMapper<RuntimeException>
return builder.build();
}
- private static class ExceptionPojo {
-
- public static ExceptionPojo create(final Exception ex) {
- return new ExceptionPojo(ex);
- }
-
- private static String format(final StackTraceElement stackTraceElement) {
- return stackTraceElement.toString();
- }
-
- private final String message;
- private final List<String> stackTrace = Lists.newArrayList();
- private ExceptionPojo causedBy;
-
- public ExceptionPojo(final Throwable ex) {
- this.message = messageFor(ex);
- final StackTraceElement[] stackTraceElements = ex.getStackTrace();
- for (final StackTraceElement stackTraceElement : stackTraceElements) {
- this.stackTrace.add(format(stackTraceElement));
- }
- final Throwable cause = ex.getCause();
- if (cause != null && cause != ex) {
- this.causedBy = new ExceptionPojo(cause);
- }
- }
-
- private static String messageFor(final Throwable ex) {
- final String message = ex.getMessage();
- return message != null ? message : ex.getClass().getName();
- }
-
- @SuppressWarnings("unused")
- public String getMessage() {
- return message;
- }
-
- @SuppressWarnings("unused")
- public List<String> getStackTrace() {
- return stackTrace;
- }
-
- @SuppressWarnings("unused")
- public ExceptionPojo getCausedBy() {
- return causedBy;
- }
- }
-
static String jsonFor(final Exception ex) {
try {
- return JsonMapper.instance().write(ExceptionPojo.create(ex));
+ return JsonMapper.instance().write(RuntimeExceptionPojo.create(ex));
} catch (final Exception e) {
// fallback
return "{ \"exception\": \"" + ExceptionUtils.getFullStackTrace(ex) + "\" }";
http://git-wip-us.apache.org/repos/asf/isis/blob/807c6ccf/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionPojo.java
----------------------------------------------------------------------
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionPojo.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionPojo.java
new file mode 100644
index 0000000..f86e4d6
--- /dev/null
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/RuntimeExceptionPojo.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.viewer.restfulobjects.server;
+
+import java.util.List;
+import javax.jdo.JDOException;
+import com.google.common.collect.Lists;
+
+class RuntimeExceptionPojo {
+
+ public static RuntimeExceptionPojo create(final Exception ex) {
+ return new RuntimeExceptionPojo(ex);
+ }
+
+ private static String format(final StackTraceElement stackTraceElement) {
+ return stackTraceElement.toString();
+ }
+
+ private final String className;
+ private final String message;
+ private final List<String> stackTrace = Lists.newArrayList();
+ private RuntimeExceptionPojo causedBy;
+
+ public RuntimeExceptionPojo(final Throwable ex) {
+ this.className = ex.getClass().getName();
+ this.message = messageFor(ex);
+ final StackTraceElement[] stackTraceElements = ex.getStackTrace();
+ for (final StackTraceElement stackTraceElement : stackTraceElements) {
+ this.stackTrace.add(format(stackTraceElement));
+ }
+
+ final Throwable cause = causeOf(ex);
+ if (cause != null && cause != ex) {
+ this.causedBy = new RuntimeExceptionPojo(cause);
+ }
+ }
+
+ private static Throwable causeOf(Throwable ex) {
+ if (ex instanceof JDOException) {
+ final JDOException jdoException = (JDOException) ex;
+ final Throwable[] nestedExceptions = jdoException.getNestedExceptions();
+ return nestedExceptions.length > 0? nestedExceptions[0]: null;
+ }
+ else {
+ return ex.getCause();
+ }
+ }
+
+ private static String messageFor(final Throwable ex) {
+ final String message = ex.getMessage();
+ return message != null ? message : ex.getClass().getName();
+ }
+
+ @SuppressWarnings("unused")
+ public String getClassName() {
+ return className;
+ }
+
+ @SuppressWarnings("unused")
+ public String getMessage() {
+ return message;
+ }
+
+ @SuppressWarnings("unused")
+ public List<String> getStackTrace() {
+ return stackTrace;
+ }
+
+ @SuppressWarnings("unused")
+ public RuntimeExceptionPojo getCausedBy() {
+ return causedBy;
+ }
+}