View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.http.response;
18  
19  import static org.apache.juneau.commons.utils.CollectionUtils.*;
20  import static org.apache.juneau.http.HttpResponses.*;
21  import static org.junit.jupiter.api.Assertions.*;
22  
23  import java.lang.reflect.*;
24  
25  import org.apache.http.*;
26  import org.apache.juneau.*;
27  import org.apache.juneau.http.header.*;
28  import org.apache.juneau.rest.annotation.*;
29  import org.apache.juneau.rest.mock.*;
30  import org.junit.jupiter.api.*;
31  
32  class HttpException_Test extends TestBase {
33  
34  	@Rest
35  	public static class A {
36  		@RestGet
37  		public void f1() throws BasicHttpException {
38  			throw new BasicHttpException(225, new RuntimeException("foo"), "bar {0}", "baz");
39  		}
40  		@RestGet
41  		public void f2() throws BasicHttpException {
42  			throw new BasicHttpException(225, "foo");
43  		}
44  		@RestGet
45  		public void f3() throws BasicHttpException {
46  			throw new BasicHttpException(225, new RuntimeException("baz"));
47  		}
48  		@RestGet
49  		public void f4() throws BasicHttpException {
50  			throw new BasicHttpException(225, "bar {0}", "baz");
51  		}
52  		@RestGet
53  		public void f5() throws BasicHttpException {
54  			throw httpException().setStatusCode2(225).setHeader2("Foo", "bar");
55  		}
56  		@RestGet
57  		public void f6() throws BasicHttpException {
58  			throw httpException().setStatusCode2(225).setHeaders(l(
59  				BasicHeader.of("X-Custom", "value1"),
60  				BasicHeader.of("X-Test", "value2")
61  			));
62  		}
63  		@RestGet
64  		public void f7() throws BasicHttpException {
65  			throw httpException().setStatusCode2(225).setContent("Custom exception content");
66  		}
67  	}
68  
69  	@Test void a01_basic() throws Exception {
70  		var c = MockRestClient.create(A.class).ignoreErrors().build();
71  
72  		c.get("/f1").run()
73  			.assertStatus().asCode().is(225)
74  			.assertContent("bar baz");
75  		c.get("/f2").run()
76  			.assertStatus().asCode().is(225)
77  			.assertContent("foo");
78  		c.get("/f3").run()
79  			.assertStatus().asCode().is(225)
80  			.assertContent("java.lang.RuntimeException: baz");
81  		c.get("/f4").run()
82  			.assertStatus().asCode().is(225)
83  			.assertContent("bar baz");
84  		c.get("/f5").run()
85  			.assertStatus().asCode().is(225)
86  			.assertContent("")
87  			.assertHeader("Foo").is("bar");
88  		c.get("/f6").run()
89  			.assertStatus().asCode().is(225)
90  			.assertHeader("X-Custom").is("value1")
91  			.assertHeader("X-Test").is("value2");
92  		c.get("/f7").run()
93  			.assertStatus().asCode().is(225)
94  			.assertContent("Custom exception content");
95  	}
96  
97  	@Test void a02_getRootCause() {
98  		var x = new BasicHttpException(100, null);
99  		assertNull(x.getRootCause());
100 
101 		x = new BasicHttpException(100, new BasicHttpException(100,"foo"));
102 		assertNull(x.getRootCause());
103 
104 		x = new BasicHttpException(100, new RuntimeException("foo"));
105 		assertInstanceOf(RuntimeException.class, x.getRootCause());
106 
107 		x = new BasicHttpException(100, new BasicHttpException(100, new RuntimeException("foo")));
108 		assertInstanceOf(RuntimeException.class, x.getRootCause());
109 
110 		x = new BasicHttpException(100, new InvocationTargetException(new RuntimeException("foo")));
111 		assertInstanceOf(RuntimeException.class, x.getRootCause());
112 	}
113 
114 	@Test void a03_getFullStackMessage() {
115 		var x = new BasicHttpException(100, null);
116 		assertEquals("Continue", x.getFullStackMessage(false));
117 		assertEquals("Continue", x.getFullStackMessage(true));
118 
119 		x = new BasicHttpException(100, "foo<bar>&baz");
120 		assertEquals("foo<bar>&baz", x.getFullStackMessage(false));
121 		assertEquals("foo bar  baz", x.getFullStackMessage(true));
122 
123 		x = new BasicHttpException(100, new RuntimeException("foo<bar>&qux"), "foo{0}","<bar>&baz");
124 		assertEquals("foo<bar>&baz\nCaused by (RuntimeException): foo<bar>&qux", x.getFullStackMessage(false));
125 		assertEquals("foo bar  baz\nCaused by (RuntimeException): foo bar  qux", x.getFullStackMessage(true));
126 
127 		x = new BasicHttpException(100, new RuntimeException(), "foo{0}","<bar>&baz");
128 		assertEquals("foo<bar>&baz\nCaused by (RuntimeException)", x.getFullStackMessage(false));
129 		assertEquals("foo bar  baz\nCaused by (RuntimeException)", x.getFullStackMessage(true));
130 	}
131 
132 	@Test void a04_fluentSetters() {
133 		var x = httpException().setStatusCode2(500);
134 
135 		// Test setHeaders(List<Header>) returns same instance for fluent chaining
136 		assertSame(x, x.setHeaders(l(
137 			BasicHeader.of("X-Fluent-Test", "fluent-value")
138 		)));
139 		assertEquals("fluent-value", x.getFirstHeader("X-Fluent-Test").getValue());
140 
141 		// Test setContent(String) returns same instance for fluent chaining
142 		assertSame(x, x.setContent("test error content"));
143 
144 		// Test setContent(HttpEntity) returns same instance for fluent chaining
145 		var x2 = httpException().setStatusCode2(500);
146 		HttpEntity entity = x2.getEntity();
147 		assertSame(x2, x2.setContent(entity));
148 	}
149 }