001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2014-2015 ForgeRock AS. 015 */ 016package org.forgerock.http.protocol; 017 018/** 019 * An HTTP Framework Exception that can be used by filters/handlers to simplify 020 * control-flow inside async call-backs. 021 * <p> 022 * As a developer, it's still useful to be able to use try-catch blocks, even if the catch block converts 023 * the {@link ResponseException} to a {@code Promise<Response, ...>}. 024 * <p> 025 * Note that this is a convenience class offered by the HTTP Framework, there is no requirement to use it in Filter 026 * or Handler implementations: 027 * <ul> 028 * <li>Ease control-flow inside async call-backs or in synchronous code</li> 029 * <li>Contains a {@link Response} that may be used to forward an error message without losing detailed 030 * information about the cause of the failure</li> 031 * <li>Contained {@link Response} may be automatically associated to this exception in order to keep track of the 032 * original failure</li> 033 * </ul> 034 * @see Response#getCause() 035 */ 036public class ResponseException extends Exception { 037 private static final long serialVersionUID = 7012424171155584261L; 038 039 private final Response response; 040 041 /** 042 * Constructs a ResponseException using the given {@code message}. 043 * 044 * @param message Error message 045 */ 046 public ResponseException(String message) { 047 this(message, null); 048 } 049 050 /** 051 * Constructs a ResponseException using the given {@code response}. 052 * The provided Response won't be linked to this exception. 053 * 054 * @param response Response 055 * @see Response#setCause(Exception) 056 * @see #getResponse() 057 */ 058 public ResponseException(Response response) { 059 this(response, null, null); 060 } 061 062 /** 063 * Constructs a ResponseException using the given {@code message} and parent {@code cause}. 064 * This constructor also build a {@link Response} object that will be linked to this exception instance. 065 * 066 * @param message Error message 067 * @param cause Error cause 068 */ 069 public ResponseException(String message, Throwable cause) { 070 this(new Response(Status.INTERNAL_SERVER_ERROR).setEntity(message), 071 message, 072 cause, 073 true); 074 } 075 076 /** 077 * Constructs a ResponseException using the given {@code response}, {@code message} and parent {@code cause}. 078 * The provided Response won't be linked to this exception. 079 * 080 * @param response response object 081 * @param message Error message 082 * @param cause Error cause 083 */ 084 public ResponseException(Response response, String message, Throwable cause) { 085 this(response, message, cause, false); 086 } 087 088 /** 089 * Constructs a ResponseException using the given {@code response}, {@code message} and parent {@code cause}, then 090 * link (if {@code link} is {@code true}) the given {@code response} to this exception. 091 * 092 * @param response response object 093 * @param message Error message 094 * @param cause Error cause 095 * @param link link this exception with the contained response 096 */ 097 private ResponseException(Response response, String message, Throwable cause, boolean link) { 098 super(message, cause); 099 this.response = response; 100 if (link) { 101 // Auto-link the response with this exception instance 102 response.setCause(this); 103 } 104 } 105 106 /** 107 * Returns the response associated to this exception. 108 * It is intended to be used when propagating a specific Response message (constructed at the point where the 109 * original error occurred) in try-catch blocks: 110 * 111 * <pre> 112 * {@code try { 113 * doSomeStuff(request); 114 * } catch (ResponseException e) { 115 * return Promises.newResultPromise(e.getResponse()); 116 * }} 117 * </pre> 118 * 119 * <p> 120 * It can also be used as an informal pointer to the message that caused the exception (Client API usage) 121 * 122 * @return the response linked to this exception. 123 */ 124 public Response getResponse() { 125 return response; 126 } 127}