Skip to content

Commit

Permalink
Implement a concrete Error class for passing to ContentTypeEngines
Browse files Browse the repository at this point in the history
Not all content-type engines are able to serialize & deserialize arbitrary Objects.
For example, JAXB can not natively serialize a collection.  To avoid internal
Pippo errors with the ContentTypeEngines, Pippo should use a concrete class
to represent an error.
  • Loading branch information
gitblit committed Jan 8, 2015
1 parent a97cb2a commit 23605ba
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ public void handle(int statusCode, Request request, Response response) {
renderHtml(statusCode, request, response);

} else {
Error error = prepareError(statusCode, request, response);
try {
Map<String, Object> locals = prepareLocals(statusCode, request, response);
response.send(locals, engine.getContentType());
response.send(error, engine.getContentType());
} catch (Exception e) {
log.error("Unexpected error rendering generating '{}' representation!", contentType, e);
log.error("Unexpected error generating '{}' as '{}'!", Error.class.getName(), contentType, e);
response.status(HttpConstants.StatusCode.INTERNAL_ERROR);
response.text(application.getMessages().get("pippo.statusCode500", request, response));
}
Expand All @@ -95,8 +95,10 @@ protected void renderHtml(int statusCode, Request request, Response response) {
renderDirectly(request, response);
} else {
try {
Map<String, Object> locals = prepareLocals(statusCode, request, response);
response.getLocals().putAll(locals);
Error error = prepareError(statusCode, request, response);
Map<String, Object> bindings = error.asMap();
bindings.putAll(prepareTemplateBindings(statusCode, request, response));
response.getLocals().putAll(bindings);
response.render(template);
} catch (Exception e) {
log.error("Unexpected error rendering your '{}' template!", template, e);
Expand All @@ -109,6 +111,11 @@ protected void renderHtml(int statusCode, Request request, Response response) {
@Override
public void handle(Exception exception, Request request, Response response) {

String message = exception.getMessage();
if (!StringUtils.isNullOrEmpty(message)) {
response.bind("message", message);
}

if (application.getPippoSettings().isDev()) {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
Expand Down Expand Up @@ -152,31 +159,45 @@ protected void renderDirectly(Request request, Response response) {
}

/**
* Get the local values for the error response.
* Get the template bindings for the error response.
*
* @param request
* @param response
* @return local values map
* @return bindings map
*/
protected Map<String, Object> prepareLocals(int statusCode, Request request, Response response) {
String messageKey = "pippo.statusCode" + statusCode;

protected Map<String, Object> prepareTemplateBindings(int statusCode, Request request, Response response) {
Map<String, Object> locals = new LinkedHashMap<>();
locals.put("applicationName", application.getApplicationName());
locals.put("applicationVersion", application.getApplicationVersion());
locals.put("runtimeMode", application.getPippoSettings().getRuntimeMode());
locals.put("statusCode", statusCode);
locals.put("statusMessage", application.getMessages().get(messageKey, request, response));
locals.put("requestMethod", request.getMethod());
locals.put("requestUri", request.getUri());

locals.put("runtimeMode", application.getPippoSettings().getRuntimeMode().toString());
if (application.getPippoSettings().isDev()) {
locals.put("routes", application.getRouter().getRoutes());
}

return locals;
}

/**
* Prepares an Error instance for the error response.
*
* @param statusCode
* @param request
* @param response
* @return an Error
*/
protected Error prepareError(int statusCode, Request request, Response response) {
String messageKey = "pippo.statusCode" + statusCode;

Error error = new Error();
error.statusCode = statusCode;
error.statusMessage = application.getMessages().get(messageKey, request, response);
error.requestMethod = request.getMethod();
error.requestUri = request.getContextUri();
error.stacktrace = (String) response.getLocals().get("stacktrace");
error.message = (String) response.getLocals().get("message");

return error;
}

protected String getTemplateForStatusCode(int statusCode) {
switch (statusCode) {
case 404:
Expand Down
70 changes: 70 additions & 0 deletions pippo-core/src/main/java/ro/fortsoft/pippo/core/Error.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (C) 2015 the original author or authors.
*
* Licensed 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 ro.fortsoft.pippo.core;

import ro.fortsoft.pippo.core.util.StringUtils;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

/**
* @author James Moger
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Error implements Serializable {

private static final long serialVersionUID = 1L;

public int statusCode;
public String statusMessage;
public String requestMethod;
public String requestUri;
public String message;
public String stacktrace;

public Error() {
}

/**
* Get the Error as a Map.
*
* @return the error as a map
*/
public Map<String, Object> asMap() {

Map<String, Object> map = new LinkedHashMap<>();
map.put("statusCode", statusCode);
map.put("statusMessage", statusMessage);
map.put("requestMethod", requestMethod);
map.put("requestUri", requestUri);

if (!StringUtils.isNullOrEmpty(message)) {
map.put("message", message);
}
if (!StringUtils.isNullOrEmpty(stacktrace)) {
map.put("stacktrace", stacktrace);
}

return map;
}

}

0 comments on commit 23605ba

Please sign in to comment.