Skip to content

Commit 34f6852

Browse files
committed
Add RSocketProtocolException in top-level package
Replaces (now deprecated) RSocketException from the exceptions package which can lead to cycles (e.g. with frame package). Other minor refinements: - error code validation - shared errorCode() implementation - error code in toString() - avoid NPE for null message, it's better to keep the original exception and null is allowed by getMessage().
1 parent f930b8e commit 34f6852

18 files changed

+221
-177
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2015-2020 the original author or authors.
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, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.rsocket;
18+
19+
import reactor.util.annotation.Nullable;
20+
21+
/**
22+
* Exception that represents an RSocket protocol error.
23+
*
24+
* @see <a href="https://github.com/rsocket/rsocket/blob/master/Protocol.md#error-frame-0x0b">ERROR
25+
* Frame (0x0B)</a>
26+
*/
27+
public class RSocketProtocolException extends RuntimeException {
28+
29+
private static final long serialVersionUID = -1628781753426267554L;
30+
31+
private final int errorCode;
32+
33+
/**
34+
* Constructor with a protocol error code and a message.
35+
*
36+
* @param errorCode the RSocket protocol error code
37+
* @param message error explanation
38+
*/
39+
public RSocketProtocolException(int errorCode, String message) {
40+
this(errorCode, message, null);
41+
}
42+
43+
/**
44+
* Alternative to {@link #RSocketProtocolException(int, String)} with a root cause.
45+
*
46+
* @param errorCode the RSocket protocol error code
47+
* @param message error explanation
48+
* @param cause a root cause for the error
49+
*/
50+
public RSocketProtocolException(int errorCode, String message, @Nullable Throwable cause) {
51+
super(message, cause);
52+
this.errorCode = errorCode;
53+
54+
// Avoid dependency on frame package
55+
if (errorCode > 0xFFFFFFFE && errorCode < 0x00000001) {
56+
throw new IllegalArgumentException(
57+
"Allowed errorCode value should be in range [0x00000001-0xFFFFFFFE]", this);
58+
}
59+
}
60+
61+
/**
62+
* Return the RSocket <a
63+
* href="https://github.com/rsocket/rsocket/blob/master/Protocol.md#error-codes">error code</a>
64+
* represented by this exception
65+
*
66+
* @return the RSocket protocol error code
67+
*/
68+
public int errorCode() {
69+
return errorCode;
70+
}
71+
72+
@Override
73+
public String toString() {
74+
return getClass().getSimpleName()
75+
+ " (0x"
76+
+ Integer.toHexString(errorCode)
77+
+ "): "
78+
+ getMessage();
79+
}
80+
}

rsocket-core/src/main/java/io/rsocket/exceptions/ApplicationErrorException.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2018 the original author or authors.
2+
* Copyright 2015-2020 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.
@@ -17,6 +17,7 @@
1717
package io.rsocket.exceptions;
1818

1919
import io.rsocket.frame.ErrorType;
20+
import javax.annotation.Nullable;
2021

2122
/**
2223
* Application layer logic generating a Reactive Streams {@code onError} event.
@@ -32,25 +33,18 @@ public final class ApplicationErrorException extends RSocketException {
3233
* Constructs a new exception with the specified message.
3334
*
3435
* @param message the message
35-
* @throws NullPointerException if {@code message} is {@code null}
3636
*/
3737
public ApplicationErrorException(String message) {
38-
super(message);
38+
this(message, null);
3939
}
4040

4141
/**
4242
* Constructs a new exception with the specified message and cause.
4343
*
4444
* @param message the message
4545
* @param cause the cause of this exception
46-
* @throws NullPointerException if {@code message} or {@code cause} is {@code null}
4746
*/
48-
public ApplicationErrorException(String message, Throwable cause) {
49-
super(message, cause);
50-
}
51-
52-
@Override
53-
public int errorCode() {
54-
return ErrorType.APPLICATION_ERROR;
47+
public ApplicationErrorException(String message, @Nullable Throwable cause) {
48+
super(ErrorType.APPLICATION_ERROR, message, cause);
5549
}
5650
}

rsocket-core/src/main/java/io/rsocket/exceptions/CanceledException.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2018 the original author or authors.
2+
* Copyright 2015-2020 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.
@@ -17,6 +17,7 @@
1717
package io.rsocket.exceptions;
1818

1919
import io.rsocket.frame.ErrorType;
20+
import javax.annotation.Nullable;
2021

2122
/**
2223
* The Responder canceled the request but may have started processing it (similar to REJECTED but
@@ -33,25 +34,18 @@ public final class CanceledException extends RSocketException {
3334
* Constructs a new exception with the specified message.
3435
*
3536
* @param message the message
36-
* @throws NullPointerException if {@code message} is {@code null}
3737
*/
3838
public CanceledException(String message) {
39-
super(message);
39+
this(message, null);
4040
}
4141

4242
/**
4343
* Constructs a new exception with the specified message and cause.
4444
*
4545
* @param message the message
4646
* @param cause the cause of this exception
47-
* @throws NullPointerException if {@code message} or {@code cause} is {@code null}
4847
*/
49-
public CanceledException(String message, Throwable cause) {
50-
super(message, cause);
51-
}
52-
53-
@Override
54-
public int errorCode() {
55-
return ErrorType.CANCELED;
48+
public CanceledException(String message, @Nullable Throwable cause) {
49+
super(ErrorType.CANCELED, message, cause);
5650
}
5751
}

rsocket-core/src/main/java/io/rsocket/exceptions/ConnectionCloseException.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2018 the original author or authors.
2+
* Copyright 2015-2020 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.
@@ -17,6 +17,7 @@
1717
package io.rsocket.exceptions;
1818

1919
import io.rsocket.frame.ErrorType;
20+
import javax.annotation.Nullable;
2021

2122
/**
2223
* The connection is being terminated. Sender or Receiver of this frame MUST wait for outstanding
@@ -33,25 +34,18 @@ public final class ConnectionCloseException extends RSocketException {
3334
* Constructs a new exception with the specified message.
3435
*
3536
* @param message the message
36-
* @throws NullPointerException if {@code message} is {@code null}
3737
*/
3838
public ConnectionCloseException(String message) {
39-
super(message);
39+
this(message, null);
4040
}
4141

4242
/**
4343
* Constructs a new exception with the specified message and cause.
4444
*
4545
* @param message the message
4646
* @param cause the cause of this exception
47-
* @throws NullPointerException if {@code message} or {@code cause} is {@code null}
4847
*/
49-
public ConnectionCloseException(String message, Throwable cause) {
50-
super(message, cause);
51-
}
52-
53-
@Override
54-
public int errorCode() {
55-
return ErrorType.CONNECTION_CLOSE;
48+
public ConnectionCloseException(String message, @Nullable Throwable cause) {
49+
super(ErrorType.CONNECTION_CLOSE, message, cause);
5650
}
5751
}

rsocket-core/src/main/java/io/rsocket/exceptions/ConnectionErrorException.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2018 the original author or authors.
2+
* Copyright 2015-2020 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.
@@ -17,6 +17,7 @@
1717
package io.rsocket.exceptions;
1818

1919
import io.rsocket.frame.ErrorType;
20+
import javax.annotation.Nullable;
2021

2122
/**
2223
* The connection is being terminated. Sender or Receiver of this frame MAY close the connection
@@ -33,25 +34,18 @@ public final class ConnectionErrorException extends RSocketException implements
3334
* Constructs a new exception with the specified message.
3435
*
3536
* @param message the message
36-
* @throws NullPointerException if {@code message} is {@code null}
3737
*/
3838
public ConnectionErrorException(String message) {
39-
super(message);
39+
this(message, null);
4040
}
4141

4242
/**
4343
* Constructs a new exception with the specified message and cause.
4444
*
4545
* @param message the message
4646
* @param cause the cause of this exception
47-
* @throws NullPointerException if {@code message} or {@code cause} is {@code null}
4847
*/
49-
public ConnectionErrorException(String message, Throwable cause) {
50-
super(message, cause);
51-
}
52-
53-
@Override
54-
public int errorCode() {
55-
return ErrorType.CONNECTION_ERROR;
48+
public ConnectionErrorException(String message, @Nullable Throwable cause) {
49+
super(ErrorType.CONNECTION_ERROR, message, cause);
5650
}
5751
}
Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,36 @@
1+
/*
2+
* Copyright 2015-2020 the original author or authors.
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, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package io.rsocket.exceptions;
218

319
import io.rsocket.frame.ErrorType;
20+
import javax.annotation.Nullable;
421

522
public class CustomRSocketException extends RSocketException {
623
private static final long serialVersionUID = 7873267740343446585L;
724

8-
private final int errorCode;
9-
1025
/**
1126
* Constructs a new exception with the specified message.
1227
*
1328
* @param errorCode customizable error code. Should be in range [0x00000301-0xFFFFFFFE]
1429
* @param message the message
15-
* @throws NullPointerException if {@code message} is {@code null}
1630
* @throws IllegalArgumentException if {@code errorCode} is out of allowed range
1731
*/
1832
public CustomRSocketException(int errorCode, String message) {
19-
super(message);
20-
if (errorCode > ErrorType.MAX_USER_ALLOWED_ERROR_CODE
21-
&& errorCode < ErrorType.MIN_USER_ALLOWED_ERROR_CODE) {
22-
throw new IllegalArgumentException(
23-
"Allowed errorCode value should be in range [0x00000301-0xFFFFFFFE]");
24-
}
25-
this.errorCode = errorCode;
33+
this(errorCode, message, null);
2634
}
2735

2836
/**
@@ -31,21 +39,14 @@ public CustomRSocketException(int errorCode, String message) {
3139
* @param errorCode customizable error code. Should be in range [0x00000301-0xFFFFFFFE]
3240
* @param message the message
3341
* @param cause the cause of this exception
34-
* @throws NullPointerException if {@code message} or {@code cause} is {@code null}
3542
* @throws IllegalArgumentException if {@code errorCode} is out of allowed range
3643
*/
37-
public CustomRSocketException(int errorCode, String message, Throwable cause) {
38-
super(message, cause);
44+
public CustomRSocketException(int errorCode, String message, @Nullable Throwable cause) {
45+
super(errorCode, message, cause);
3946
if (errorCode > ErrorType.MAX_USER_ALLOWED_ERROR_CODE
4047
&& errorCode < ErrorType.MIN_USER_ALLOWED_ERROR_CODE) {
4148
throw new IllegalArgumentException(
42-
"Allowed errorCode value should be in range [0x00000301-0xFFFFFFFE]");
49+
"Allowed errorCode value should be in range [0x00000301-0xFFFFFFFE]", this);
4350
}
44-
this.errorCode = errorCode;
45-
}
46-
47-
@Override
48-
public int errorCode() {
49-
return errorCode;
5051
}
5152
}

rsocket-core/src/main/java/io/rsocket/exceptions/Exceptions.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2018 the original author or authors.
2+
* Copyright 2015-2020 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.
@@ -16,7 +16,18 @@
1616

1717
package io.rsocket.exceptions;
1818

19-
import static io.rsocket.frame.ErrorFrameFlyweight.*;
19+
import static io.rsocket.frame.ErrorFrameFlyweight.APPLICATION_ERROR;
20+
import static io.rsocket.frame.ErrorFrameFlyweight.CANCELED;
21+
import static io.rsocket.frame.ErrorFrameFlyweight.CONNECTION_CLOSE;
22+
import static io.rsocket.frame.ErrorFrameFlyweight.CONNECTION_ERROR;
23+
import static io.rsocket.frame.ErrorFrameFlyweight.INVALID;
24+
import static io.rsocket.frame.ErrorFrameFlyweight.INVALID_SETUP;
25+
import static io.rsocket.frame.ErrorFrameFlyweight.MAX_USER_ALLOWED_ERROR_CODE;
26+
import static io.rsocket.frame.ErrorFrameFlyweight.MIN_USER_ALLOWED_ERROR_CODE;
27+
import static io.rsocket.frame.ErrorFrameFlyweight.REJECTED;
28+
import static io.rsocket.frame.ErrorFrameFlyweight.REJECTED_RESUME;
29+
import static io.rsocket.frame.ErrorFrameFlyweight.REJECTED_SETUP;
30+
import static io.rsocket.frame.ErrorFrameFlyweight.UNSUPPORTED_SETUP;
2031

2132
import io.netty.buffer.ByteBuf;
2233
import io.rsocket.frame.ErrorFrameFlyweight;
@@ -28,10 +39,11 @@ public final class Exceptions {
2839
private Exceptions() {}
2940

3041
/**
31-
* Create a {@link RSocketException} from a Frame that matches the error code it contains.
42+
* Create a {@link io.rsocket.RSocketProtocolException} from a Frame that matches the error code
43+
* it contains.
3244
*
3345
* @param frame the frame to retrieve the error code and message from
34-
* @return a {@link RSocketException} that matches the error code in the Frame
46+
* @return a {@link io.rsocket.RSocketProtocolException} that matches the error code in the Frame
3547
* @throws NullPointerException if {@code frame} is {@code null}
3648
*/
3749
public static RuntimeException from(int streamId, ByteBuf frame) {

0 commit comments

Comments
 (0)