1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.yarn.webapp; 19 20 import java.io.FileNotFoundException; 21 import java.io.IOException; 22 23 import javax.servlet.http.HttpServletResponse; 24 import javax.ws.rs.WebApplicationException; 25 import javax.ws.rs.core.Context; 26 import javax.ws.rs.core.Response; 27 import javax.ws.rs.ext.ExceptionMapper; 28 import javax.ws.rs.ext.Provider; 29 import javax.xml.bind.UnmarshalException; 30 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 import org.apache.hadoop.classification.InterfaceAudience; 34 import org.apache.hadoop.ipc.RemoteException; 35 import org.apache.hadoop.security.authorize.AuthorizationException; 36 37 import com.google.inject.Singleton; 38 39 /** 40 * Handle webservices jersey exceptions and create json or xml response 41 * with the ExceptionData. 42 */ 43 @InterfaceAudience.LimitedPrivate({"YARN", "MapReduce"}) 44 @Singleton 45 @Provider 46 public class GenericExceptionHandler implements ExceptionMapper<Exception> { 47 public static final Log LOG = LogFactory 48 .getLog(GenericExceptionHandler.class); 49 50 private @Context 51 HttpServletResponse response; 52 53 @Override toResponse(Exception e)54 public Response toResponse(Exception e) { 55 if (LOG.isTraceEnabled()) { 56 LOG.trace("GOT EXCEPITION", e); 57 } 58 // Don't catch this as filter forward on 404 59 // (ServletContainer.FEATURE_FILTER_FORWARD_ON_404) 60 // won't work and the web UI won't work! 61 if (e instanceof com.sun.jersey.api.NotFoundException) { 62 return ((com.sun.jersey.api.NotFoundException) e).getResponse(); 63 } 64 // clear content type 65 response.setContentType(null); 66 67 // Convert exception 68 if (e instanceof RemoteException) { 69 e = ((RemoteException) e).unwrapRemoteException(); 70 } 71 72 // Map response status 73 final Response.Status s; 74 if (e instanceof SecurityException) { 75 s = Response.Status.UNAUTHORIZED; 76 } else if (e instanceof AuthorizationException) { 77 s = Response.Status.UNAUTHORIZED; 78 } else if (e instanceof FileNotFoundException) { 79 s = Response.Status.NOT_FOUND; 80 } else if (e instanceof NotFoundException) { 81 s = Response.Status.NOT_FOUND; 82 } else if (e instanceof IOException) { 83 s = Response.Status.NOT_FOUND; 84 } else if (e instanceof ForbiddenException) { 85 s = Response.Status.FORBIDDEN; 86 } else if (e instanceof UnsupportedOperationException) { 87 s = Response.Status.BAD_REQUEST; 88 } else if (e instanceof IllegalArgumentException) { 89 s = Response.Status.BAD_REQUEST; 90 } else if (e instanceof NumberFormatException) { 91 s = Response.Status.BAD_REQUEST; 92 } else if (e instanceof BadRequestException) { 93 s = Response.Status.BAD_REQUEST; 94 } else if (e instanceof WebApplicationException 95 && e.getCause() instanceof UnmarshalException) { 96 s = Response.Status.BAD_REQUEST; 97 } else { 98 LOG.warn("INTERNAL_SERVER_ERROR", e); 99 s = Response.Status.INTERNAL_SERVER_ERROR; 100 } 101 102 // let jaxb handle marshalling data out in the same format requested 103 RemoteExceptionData exception = new RemoteExceptionData(e.getClass().getSimpleName(), 104 e.getMessage(), e.getClass().getName()); 105 106 return Response.status(s).entity(exception) 107 .build(); 108 } 109 } 110