Skip to content

Commit cfeaeca

Browse files
artembilangaryrussell
authored andcommitted
GH-3421: Resolve throws Exception; in the API
Fixes #3421 Remove `throws Exception;` from production code to honor the rule `Generic exceptions should never be thrown` which is enabled on SonarQube * Rework affected usages to `try..catch` with throwing respective runtime exception or just logging * Some other refactoring for the affected classes
1 parent a08713f commit cfeaeca

File tree

4 files changed

+73
-66
lines changed

4 files changed

+73
-66
lines changed

spring-integration-mail/src/main/java/org/springframework/integration/mail/transformer/AbstractMailMessageTransformer.java

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,16 +39,14 @@
3939
* @author Gary Russell
4040
* @author Artem Bilan
4141
*/
42-
public abstract class AbstractMailMessageTransformer<T> implements Transformer,
43-
BeanFactoryAware {
42+
public abstract class AbstractMailMessageTransformer<T> implements Transformer, BeanFactoryAware {
4443

4544
private BeanFactory beanFactory;
4645

4746
private MessageBuilderFactory messageBuilderFactory = new DefaultMessageBuilderFactory();
4847

4948
private boolean messageBuilderFactorySet;
5049

51-
5250
@Override
5351
public final void setBeanFactory(BeanFactory beanFactory) {
5452
this.beanFactory = beanFactory;
@@ -67,28 +65,19 @@ protected MessageBuilderFactory getMessageBuilderFactory() {
6765
@Override
6866
public Message<?> transform(Message<?> message) {
6967
Object payload = message.getPayload();
70-
if (!(payload instanceof jakarta.mail.Message)) {
68+
if (!(payload instanceof jakarta.mail.Message mailMessage)) {
7169
throw new MessageTransformationException(message, getClass().getSimpleName()
7270
+ " requires a jakarta.mail.Message payload");
7371
}
74-
jakarta.mail.Message mailMessage = (jakarta.mail.Message) payload;
7572
AbstractIntegrationMessageBuilder<T> builder;
76-
try {
77-
builder = this.doTransform(mailMessage);
78-
}
79-
catch (Exception e) {
80-
throw new MessageTransformationException(message, "failed to transform mail message", e);
81-
}
73+
builder = doTransform(mailMessage);
8274
if (builder == null) {
8375
throw new MessageTransformationException(message, "failed to transform mail message");
8476
}
85-
builder.copyHeaders(extractHeaderMapFromMailMessage(mailMessage));
86-
return builder.build();
77+
return builder.copyHeaders(extractHeaderMapFromMailMessage(mailMessage)).build();
8778
}
8879

89-
protected abstract AbstractIntegrationMessageBuilder<T> doTransform(jakarta.mail.Message mailMessage)
90-
throws Exception; // NOSONAR
91-
80+
protected abstract AbstractIntegrationMessageBuilder<T> doTransform(jakarta.mail.Message mailMessage);
9281

9382
private static Map<String, Object> extractHeaderMapFromMailMessage(jakarta.mail.Message mailMessage) {
9483
return MailUtils.extractStandardHeaders(mailMessage);

spring-integration-mail/src/main/java/org/springframework/integration/mail/transformer/MailToStringTransformer.java

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323
import jakarta.mail.Part;
2424

2525
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
26+
import org.springframework.integration.transformer.MessageTransformationException;
2627
import org.springframework.util.Assert;
2728

2829
/**
@@ -51,27 +52,34 @@ public void setCharset(String charset) {
5152
}
5253

5354
@Override
54-
protected AbstractIntegrationMessageBuilder<String> doTransform(jakarta.mail.Message mailMessage)
55-
throws Exception { // NOSONAR
55+
protected AbstractIntegrationMessageBuilder<String> doTransform(jakarta.mail.Message mailMessage) {
56+
try {
57+
String payload;
58+
Object content = mailMessage.getContent();
59+
if (content instanceof String value) {
60+
payload = value;
61+
}
62+
else if (content instanceof Multipart multipart) {
63+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
64+
multipart.writeTo(outputStream);
65+
payload = outputStream.toString(this.charset);
66+
}
67+
else if (content instanceof Part part) {
68+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
69+
part.writeTo(outputStream);
70+
payload = outputStream.toString(this.charset);
71+
}
72+
else {
73+
throw new IllegalArgumentException("failed to transform contentType ["
74+
+ mailMessage.getContentType() + "] to String.");
75+
}
5676

57-
Object content = mailMessage.getContent();
58-
if (content instanceof String) {
59-
return this.getMessageBuilderFactory().withPayload((String) content);
77+
return getMessageBuilderFactory().withPayload(payload);
6078
}
61-
if (content instanceof Multipart) {
62-
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
63-
((Multipart) content).writeTo(outputStream);
64-
return this.getMessageBuilderFactory().withPayload(
65-
new String(outputStream.toByteArray(), this.charset));
79+
catch (Exception ex) {
80+
throw new MessageTransformationException("Cannot transform mail message", ex);
6681
}
67-
else if (content instanceof Part) {
68-
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
69-
((Part) content).writeTo(outputStream);
70-
return this.getMessageBuilderFactory().withPayload(
71-
new String(outputStream.toByteArray(), this.charset));
72-
}
73-
throw new IllegalArgumentException("failed to transform contentType ["
74-
+ mailMessage.getContentType() + "] to String.");
82+
7583
}
7684

7785
}

spring-integration-websocket/src/main/java/org/springframework/integration/websocket/WebSocketListener.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2019 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,25 +42,20 @@ public interface WebSocketListener extends SubProtocolCapable {
4242
* Handle the received {@link WebSocketMessage}.
4343
* @param session the WebSocket session
4444
* @param message the WebSocket message
45-
* @throws Exception the 'onMessage' Exception
4645
*/
47-
void onMessage(WebSocketSession session, WebSocketMessage<?> message)
48-
throws Exception; // NOSONAR Remove in 5.2
46+
void onMessage(WebSocketSession session, WebSocketMessage<?> message);
4947

5048
/**
5149
* Invoked after a {@link WebSocketSession} has started.
5250
* @param session the WebSocket session
53-
* @throws Exception the 'afterSessionStarted' Exception
5451
*/
55-
void afterSessionStarted(WebSocketSession session) throws Exception; // NOSONAR Remove in 5.2
52+
void afterSessionStarted(WebSocketSession session);
5653

5754
/**
5855
* Invoked after a {@link WebSocketSession} has ended.
5956
* @param session the WebSocket session
6057
* @param closeStatus the reason why the session was closed
61-
* @throws Exception the 'afterSessionEnded' Exception
6258
*/
63-
void afterSessionEnded(WebSocketSession session, CloseStatus closeStatus)
64-
throws Exception; // NOSONAR Remove in 5.2
59+
void afterSessionEnded(WebSocketSession session, CloseStatus closeStatus);
6560

6661
}

spring-integration-websocket/src/main/java/org/springframework/integration/websocket/inbound/WebSocketInboundChannelAdapter.java

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2021 the original author or authors.
2+
* Copyright 2014-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -224,39 +224,54 @@ public List<String> getSubProtocols() {
224224
}
225225

226226
@Override
227-
public void afterSessionStarted(WebSocketSession session) throws Exception { // NOSONAR Thrown from the delegate
227+
public void afterSessionStarted(WebSocketSession session) {
228228
if (isActive()) {
229-
SubProtocolHandler protocolHandler = this.subProtocolHandlerRegistry.findProtocolHandler(session);
230-
protocolHandler.afterSessionStarted(session, this.subProtocolHandlerChannel);
231-
if (!this.server && protocolHandler instanceof StompSubProtocolHandler) {
232-
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECT);
233-
accessor.setSessionId(session.getId());
234-
accessor.setLeaveMutable(true);
235-
accessor.setAcceptVersion("1.1,1.2");
236-
237-
Message<?> connectMessage = MessageBuilder.createMessage(EMPTY_PAYLOAD, accessor.getMessageHeaders());
238-
protocolHandler.handleMessageToClient(session, connectMessage);
229+
try {
230+
SubProtocolHandler protocolHandler = this.subProtocolHandlerRegistry.findProtocolHandler(session);
231+
protocolHandler.afterSessionStarted(session, this.subProtocolHandlerChannel);
232+
if (!this.server && protocolHandler instanceof StompSubProtocolHandler) {
233+
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECT);
234+
accessor.setSessionId(session.getId());
235+
accessor.setLeaveMutable(true);
236+
accessor.setAcceptVersion("1.1,1.2");
237+
238+
Message<?> connectMessage =
239+
MessageBuilder.createMessage(EMPTY_PAYLOAD, accessor.getMessageHeaders());
240+
protocolHandler.handleMessageToClient(session, connectMessage);
241+
}
242+
}
243+
catch (Exception ex) {
244+
logger.error(ex, () -> "WebSocketHandler.afterConnectionEstablished threw exception in " + this);
239245
}
240246
}
241247
}
242248

243249
@Override
244-
public void afterSessionEnded(WebSocketSession session, CloseStatus closeStatus)
245-
throws Exception { // NOSONAR Thrown from the delegate
250+
public void afterSessionEnded(WebSocketSession session, CloseStatus closeStatus) {
246251

247252
if (isActive()) {
248-
this.subProtocolHandlerRegistry.findProtocolHandler(session)
249-
.afterSessionEnded(session, closeStatus, this.subProtocolHandlerChannel);
253+
try {
254+
this.subProtocolHandlerRegistry.findProtocolHandler(session)
255+
.afterSessionEnded(session, closeStatus, this.subProtocolHandlerChannel);
256+
}
257+
catch (Exception ex) {
258+
logger.warn(ex, () -> "Unhandled exception after connection closed for " + this);
259+
}
250260
}
251261
}
252262

253263
@Override
254-
public void onMessage(WebSocketSession session, WebSocketMessage<?> webSocketMessage)
255-
throws Exception { // NOSONAR Thrown from the delegate
256-
264+
public void onMessage(WebSocketSession session, WebSocketMessage<?> webSocketMessage) {
257265
if (isActive()) {
258-
this.subProtocolHandlerRegistry.findProtocolHandler(session)
259-
.handleMessageFromClient(session, webSocketMessage, this.subProtocolHandlerChannel);
266+
try {
267+
this.subProtocolHandlerRegistry.findProtocolHandler(session)
268+
.handleMessageFromClient(session, webSocketMessage, this.subProtocolHandlerChannel);
269+
}
270+
catch (Exception ex) {
271+
logger.error(ex,
272+
() -> "SubProtocolHandler.handleMessageFromClient threw an exception on message: " +
273+
webSocketMessage + " in " + this);
274+
}
260275
}
261276
}
262277

0 commit comments

Comments
 (0)