Thomas Vachuska
Committed by Ray Milkey

ONOS-2124 Improved web-exception handling when an anonymous exception, i.e. one …

…without a message, is raised.

Top stack-frame will be used as a message if exception has no message of its own.

Change-Id: I28d68e05a0d805c7320e133d8e17081513cb503c
...@@ -21,6 +21,8 @@ import com.fasterxml.jackson.databind.node.ObjectNode; ...@@ -21,6 +21,8 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
21 import javax.ws.rs.core.Response; 21 import javax.ws.rs.core.Response;
22 import javax.ws.rs.ext.ExceptionMapper; 22 import javax.ws.rs.ext.ExceptionMapper;
23 23
24 +import static com.google.common.base.Strings.isNullOrEmpty;
25 +
24 /** 26 /**
25 * Base exception mapper implementation. 27 * Base exception mapper implementation.
26 */ 28 */
...@@ -49,9 +51,27 @@ public abstract class AbstractMapper<E extends Throwable> implements ExceptionMa ...@@ -49,9 +51,27 @@ public abstract class AbstractMapper<E extends Throwable> implements ExceptionMa
49 protected Response.ResponseBuilder response(Response.Status status, 51 protected Response.ResponseBuilder response(Response.Status status,
50 Throwable exception) { 52 Throwable exception) {
51 ObjectMapper mapper = new ObjectMapper(); 53 ObjectMapper mapper = new ObjectMapper();
54 + String message = messageFrom(exception);
52 ObjectNode result = mapper.createObjectNode() 55 ObjectNode result = mapper.createObjectNode()
53 .put("code", status.getStatusCode()) 56 .put("code", status.getStatusCode())
54 - .put("message", exception.getMessage()); 57 + .put("message", message);
55 return Response.status(status).entity(result.toString()); 58 return Response.status(status).entity(result.toString());
56 } 59 }
60 +
61 + /**
62 + * Produces a response message from the supplied exception. Either it will
63 + * use the exception message, if there is one, or it will use the top
64 + * stack-frame message.
65 + *
66 + * @param exception exception from which to produce a message
67 + * @return response message
68 + */
69 + protected String messageFrom(Throwable exception) {
70 + if (isNullOrEmpty(exception.getMessage())) {
71 + StackTraceElement[] trace = exception.getStackTrace();
72 + return trace.length == 0 ? "Unknown error" : trace[0].toString();
73 + }
74 + return exception.getMessage();
75 + }
76 +
57 } 77 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.rest.exceptions;
17 +
18 +import org.junit.Test;
19 +
20 +import static org.junit.Assert.*;
21 +
22 +/**
23 + * Set of tests for the various exception mappers.
24 + */
25 +public class ExceptionMapperTest {
26 +
27 + @Test
28 + public void emptyMessage() {
29 + RuntimeException exception = new NullPointerException();
30 + ServerErrorMapper mapper = new ServerErrorMapper();
31 + Object response = mapper.toResponse(exception).getEntity();
32 + assertTrue("incorrect response",
33 + response.toString().contains("ExceptionMapperTest.emptyMessage("));
34 + }
35 +}
...\ No newline at end of file ...\ No newline at end of file