Skip to content

Commit b4c029c

Browse files
committed
updates per code review, simplification.
1 parent 69df407 commit b4c029c

File tree

5 files changed

+66
-32
lines changed

5 files changed

+66
-32
lines changed

src/main/java/io/fusionauth/http/server/Configurable.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,12 @@ default T withShutdownDuration(Duration duration) {
333333

334334
/**
335335
*
336-
* Sets the unexpected exception handler that may occur while processing an HTTP request. This can be set to null which means the HTTP
337-
* worker will use the default behavior.
336+
* Sets the unexpected exception handler. This handler will be called when an unexpected exception is taken while processing the HTTP
337+
* request by the HTTP worker.
338+
* <p>
339+
* This allows you to customize the status code and logging behavior.
340+
* <p>
341+
* Must not be null.
338342
*
339343
* @param unexpectedExceptionHandler The unexpected exception handler.
340344
* @return This.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2025, FusionAuth, All Rights Reserved
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,
11+
* software distributed under the License is distributed on an
12+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
* either express or implied. See the License for the specific
14+
* language governing permissions and limitations under the License.
15+
*/
16+
package io.fusionauth.http.server;
17+
18+
import io.fusionauth.http.log.Logger;
19+
20+
/**
21+
* THe default HTTP unexpected exception handler.
22+
*
23+
* @author Daniel DeGroff
24+
*/
25+
public class DefaultHTTPUnexpectedExceptionHandler implements HTTPUnexpectedExceptionHandler {
26+
27+
@Override
28+
public int handle(Logger logger, Throwable t) {
29+
int internalServerError = 500;
30+
logger.error(String.format("[%s] Closing socket with status [%d]. An HTTP worker threw an exception while processing a request.", Thread.currentThread().threadId(), internalServerError), t);
31+
return internalServerError;
32+
}
33+
}

src/main/java/io/fusionauth/http/server/HTTPServerConfiguration.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public class HTTPServerConfiguration implements Configurable<HTTPServerConfigura
7979

8080
private Duration shutdownDuration = Duration.ofSeconds(10);
8181

82-
private HTTPUnexpectedExceptionHandler unexpectedExceptionHandler;
82+
private HTTPUnexpectedExceptionHandler unexpectedExceptionHandler = new DefaultHTTPUnexpectedExceptionHandler();
8383

8484
private Duration writeThroughputCalculationDelayDuration = Duration.ofSeconds(5);
8585

@@ -112,14 +112,6 @@ public String getContextPath() {
112112
return contextPath;
113113
}
114114

115-
/**
116-
* @return The HTTP unexpected exception handler for this server or null if a default was not set.
117-
*/
118-
public HTTPUnexpectedExceptionHandler getDefaultExceptionHandler() {
119-
return unexpectedExceptionHandler;
120-
}
121-
122-
123115
/**
124116
* @return The expect validator. Cannot be null and is required.
125117
*/
@@ -285,6 +277,13 @@ public Duration getShutdownDuration() {
285277
return shutdownDuration;
286278
}
287279

280+
/**
281+
* @return The HTTP unexpected exception handler for this server or null if a default was not set.
282+
*/
283+
public HTTPUnexpectedExceptionHandler getUnexpectedExceptionHandler() {
284+
return unexpectedExceptionHandler;
285+
}
286+
288287
/**
289288
* @return the duration that will be used to delay the calculation and enforcement of the minimum write throughput.
290289
*/

src/main/java/io/fusionauth/http/server/HTTPUnexpectedExceptionHandler.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,24 @@
1515
*/
1616
package io.fusionauth.http.server;
1717

18+
import io.fusionauth.http.log.Logger;
19+
20+
/**
21+
* An interface defining the HTTP unexpected exception handler contract.
22+
*
23+
* @author Daniel DeGroff
24+
*/
1825
public interface HTTPUnexpectedExceptionHandler {
1926
/**
2027
*
21-
* @param response the HTTP response, may be null.
22-
* @param t the unexpected exception to handle.
28+
* This handler will be called when an unexpected exception is taken while processing an HTTP request by the HTTP worker.
29+
* <p>
30+
* The intent is that this provides additional flexibility on the status code and the logging behavior when an unexpected exception
31+
* caught.
32+
*
33+
* @param logger the HTTP worker logger.
34+
* @param t the unexpected exception to handle.
35+
* @return the desired HTTP status code. Note that if the response has already been committed this will be ignored.
2336
*/
24-
void handle(HTTPResponse response, Throwable t);
37+
int handle(Logger logger, Throwable t);
2538
}

src/main/java/io/fusionauth/http/server/internal/HTTPWorker.java

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import io.fusionauth.http.server.HTTPRequest;
3737
import io.fusionauth.http.server.HTTPResponse;
3838
import io.fusionauth.http.server.HTTPServerConfiguration;
39-
import io.fusionauth.http.server.HTTPUnexpectedExceptionHandler;
4039
import io.fusionauth.http.server.Instrumenter;
4140
import io.fusionauth.http.server.io.ConnectionClosedException;
4241
import io.fusionauth.http.server.io.HTTPInputStream;
@@ -268,24 +267,10 @@ public void run() {
268267
logger.debug(String.format("[%s] Closing socket with status [%d]. An IO exception was thrown during processing. These are pretty common.", Thread.currentThread().threadId(), Status.InternalServerError), e);
269268
closeSocketOnError(response, Status.InternalServerError);
270269
} catch (Throwable e) {
271-
HTTPUnexpectedExceptionHandler unexpectedExceptionHandler = configuration.getDefaultExceptionHandler();
272270
var status = Status.InternalServerError;
273-
if (unexpectedExceptionHandler != null) {
274-
if (response != null) {
275-
// Set the initial status, allowing the handler to attempt to modify the status code.
276-
response.setHeader(Headers.Connection, Connections.Close);
277-
response.setStatus(status);
278-
}
279-
280-
try {
281-
unexpectedExceptionHandler.handle(response, e);
282-
} catch (Throwable ignore) {
283-
}
284-
285-
status = response != null ? response.getStatus() : status;
286-
} else {
287-
// Log the error
288-
logger.error(String.format("[%s] Closing socket with status [%d]. An HTTP worker threw an exception while processing a request.", Thread.currentThread().threadId(), status), e);
271+
try {
272+
status = configuration.getUnexpectedExceptionHandler().handle(logger, e);
273+
} catch (Throwable ignore) {
289274
}
290275

291276
// Signal an error

0 commit comments

Comments
 (0)