Skip to content

Commit 5d51bef

Browse files
committed
Merge branch 'feature/message-format-eids' into develop
2 parents 08e334a + a32cfbf commit 5d51bef

15 files changed

+1125
-208
lines changed

README.md

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
[![Build Status](https://travis-ci.org/wavesoftware/java-eid-exceptions.svg?branch=master)](https://travis-ci.org/wavesoftware/java-eid-exceptions) [![Coverage Status](https://coveralls.io/repos/wavesoftware/java-eid-exceptions/badge.svg?branch=master&service=github)](https://coveralls.io/github/wavesoftware/java-eid-exceptions?branch=master) [![SonarQube Tech Debt](https://img.shields.io/sonar/http/sonar-ro.wavesoftware.pl/pl.wavesoftware:eid-exceptions/tech_debt.svg)](http://sonar-ro.wavesoftware.pl/dashboard/index/2600) [![Dependency Status](https://www.versioneye.com/user/projects/55aafc74306535001b000440/badge.svg?style=flat)](https://www.versioneye.com/user/projects/55aafc74306535001b000440) [![Maven Central](https://img.shields.io/maven-central/v/pl.wavesoftware/eid-exceptions.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22pl.wavesoftware%22%20AND%20a%3A%22eid-exceptions%22)
44

5-
This small library holds a set of Exceptions that implements idea of fast, reusable, error codes that can be simple thrown fast in case of unpredictable and unrecoverable application failure.
5+
This small library holds a set of exceptions and utilities that implements idea of fast, reusable, error codes that can be simply thrown fast in case of unpredictable and unrecoverable application failure. It is meant to be used for application bugs.
66

77
## Idea
88

9-
The idea is to use a set of simple runtime exceptions. They should always take the field Exception ID (Eid) in the making. This field will then be reported when displaying or logging that exception. It can also be viewed on the professional fatal error window of the application as a bug reference. EidRuntimeExceptions contains also additional unique ID to identify each single exception. This approach simplifies the management of exceptions in the application and allows developers to focus on functionalities rather than coming up with the correct statement for the exception.
9+
The idea is to use a set of simple runtime exceptions. They should always take the Exception ID (Eid) object in the making. This eid object will then be reported when displaying or logging that exception. It can also be viewed on the professional fatal error window of the application as a bug reference. EidRuntimeExceptions contains also additional unique ID to distinguish each single exception from others with same Eid. This approach simplifies the management of exceptions in the application and allows developers to focus on functionalities rather than coming up with the correct statement for the exception.
1010

1111
This approach is best to use with tools and plugins like:
1212

@@ -43,17 +43,17 @@ This classes shouldn't be used in any public API or library. It is designed to b
4343
<dependency>
4444
<groupId>pl.wavesoftware</groupId>
4545
<artifactId>eid-exceptions</artifactId>
46-
<version>1.0.0</version>
46+
<version>1.1.0</version>
4747
</dependency>
4848
```
4949

5050
### `EidPreconditions` class
5151

5252
#### General use
5353

54-
Static convenience methods that help a method or constructor check whether it was invoked correctly (whether its preconditions have been met). These methods generally accept a `boolean` expression which is expected to be `true` (or in the case of `checkNotNull`, an object reference which is expected to be non-null). When `false` (or `null`) is passed instead, the `EidPreconditions` method throws an unchecked exception, which helps the calling method communicate to its caller that that caller has made a mistake.
54+
`EidPreconditions` class consists static methods that help to use Eid in a method or constructor. This is solely for convenience purposes. Use them to check whether method or constructor was invoked correctly (whether its preconditions have been met). These methods generally accept a `boolean` expression which is expected to be `true` (or in the case of `checkNotNull`, an object reference which is expected to be non-null). When `false` (or `null`) is passed instead, the `EidPreconditions` method throws an unchecked exception, which helps the calling method communicate to its caller that that caller has made a mistake.
5555

56-
Each method accepts a EID string or Eid object, which is designed to ease of use and provide strict ID for given exception usage. This approach speed up development of large application and helps support teams by giving both static and random ID for each possible unpredicted bug.
56+
Each method accepts a EID string or Eid object, which is designed to ease of use and provide strict ID for given exception usage. This approach speed up development of large application and helps support teams by giving both static and random ID for each possible bug that could occur.
5757

5858
Each example uses static import:
5959

@@ -104,23 +104,66 @@ String nonNullUserName = checkNotNull(userName, "20150721:115515");
104104
```java
105105
checkElementIndex(index, list.size(), "20150721:115749");
106106
```
107+
108+
#### Formatted message support
109+
110+
From release `1.1.0` there have been added methods to support additional formatted messages for `checkArgument`, `checkState`, `checkNotNull` and `checkElementIndex` method. Those method versions can sometimes be used to pass additional information to exceptions that will be displayed in log files.
111+
112+
Message formatting is done using `String.format(String, Object[])` method.
113+
114+
For example:
115+
116+
```java
117+
checkState(transation.isValid(), "20151119:120238", "Invalid transaction: %s, transaction);
118+
```
119+
120+
Will produce output similar to;
121+
122+
```
123+
pl.wavesoftware.eid.exceptions.EidIllegalStateException: [20151119:120238]<xf4j1l> => Invalid transaction: <Transaction id=null, buyer=null, products=[]>
124+
```
107125
108126
#### Functional try to execute blocks
109127
110-
Using functional blocks to handle operations, that are intended to operate properly, simplify the code and makes it more readable. It's also good way to deal with untested, uncovered `catch` blocks. It's easy and gives developers nice way of dealing with countless operations that suppose to work as intended.
128+
You can use functional blocks to handle operations, that are intended to operate properly. This approach simplify the code and makes it more readable. It's also good way to deal with untested, uncovered `catch` blocks. It's easy and gives developers nice way of dealing with countless operations that suppose to work as intended.
129+
130+
There are two versions. One with `UnsafeSupplier` and one with `UnsafeProcedure`. The difference is that unsafe procedure do not return anything.
111131
112132
Example:
113133
114134
```java
115-
InputStream is = EidPreconditions.tryToExecute(new RiskyCode<InputStream>() {
135+
InputStream is = EidPreconditions.tryToExecute(new UnsafeSupplier<InputStream>() {
116136
@Override
117-
public InputStream execute() throws IOException {
137+
public InputStream get() throws IOException {
118138
return this.getClass().getClassLoader()
119139
.getResourceAsStream("project.properties");
120140
}
121141
}, "20150718:121521");
122142
```
123143
144+
or with Java 8:
145+
146+
```java
147+
import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute;
148+
// [..]
149+
InputStream is = tryToExecute(() -> { resource("project.properties"); }, "20150718:121521");
150+
```
151+
152+
#### Logging
153+
154+
Eid object can also be useful in logging. That are `makeLogMessage` method provided to do that. Message formatting is done using `String.format(String, Object[])` method.
155+
For example:
156+
157+
```java
158+
log.debug(new Eid("20151119:121814").makeLogMessage("REST request received: %s", request));
159+
```
160+
161+
will unfold to something similar to:
162+
163+
```
164+
2017-01-08T16:45:34,334 DEBUG [a.b.c.RestBroker] [20151119:121814]<d1afca> REST request received: <RestRequest user=<User id=345> flow=ShowLastTransactions step=Confirm>
165+
```
166+
124167
###Contributing
125168
126169
Contributions are welcome!
@@ -141,8 +184,12 @@ Even if you can't contribute code, if you have an idea for an improvement please
141184
142185
### Releases
143186
187+
- 1.1.0
188+
- Adding support for formatted messages in exceptions and also in utility methods of `EidPreconditions`
189+
- 1.0.1
190+
- Fixed handling for throwables as a cause with `message == null`. `cause.toString()` method is used
144191
- 1.0.0
145-
- Support for JDK >= 1.6
192+
- Support for JDK >= 1.6
146193
- 0.1.0
147-
- initial release
148-
- idea imported from Guava Library and COI code
194+
- initial release
195+
- idea imported from Guava Library and COI code

pom.xml

Lines changed: 114 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<groupId>pl.wavesoftware</groupId>
1212
<artifactId>eid-exceptions</artifactId>
13-
<version>1.0.2-SNAPSHOT</version>
13+
<version>1.1.0-SNAPSHOT</version>
1414
<packaging>jar</packaging>
1515

1616
<name>EID Runtime Exceptions and Utilities</name>
@@ -22,9 +22,13 @@
2222
<properties>
2323
<netbeans.hint.license>apache20</netbeans.hint.license>
2424
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
25+
<sonar.working.directory>${project.build.directory}/sonar</sonar.working.directory>
26+
<sonar.host.url>https://sonar.wavesoftware.pl</sonar.host.url>
2527
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
26-
<maven.compiler.source>1.6</maven.compiler.source>
27-
<maven.compiler.target>1.6</maven.compiler.target>
28+
<sonar.java.source>6</sonar.java.source>
29+
<java.source.version>${sonar.java.source}</java.source.version>
30+
<maven.compiler.source>1.${java.source.version}</maven.compiler.source>
31+
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
2832
<coveralls.skip>${skipTests}</coveralls.skip>
2933
</properties>
3034

@@ -41,6 +45,7 @@
4145
<developerConnection>scm:git:[email protected]:wavesoftware/java-eid-exceptions.git</developerConnection>
4246
<url>https://github.com/wavesoftware/java-eid-exceptions</url>
4347
</scm>
48+
4449
<ciManagement>
4550
<system>travis-ci</system>
4651
<url>https://travis-ci.org/wavesoftware/java-eid-exceptions</url>
@@ -65,7 +70,7 @@
6570
<dependency>
6671
<groupId>com.google.code.findbugs</groupId>
6772
<artifactId>jsr305</artifactId>
68-
<version>3.0.0</version>
73+
<version>3.0.1</version>
6974
<type>jar</type>
7075
</dependency>
7176
<dependency>
@@ -87,8 +92,7 @@
8792
<plugin>
8893
<groupId>org.jacoco</groupId>
8994
<artifactId>jacoco-maven-plugin</artifactId>
90-
<!-- Version pin because 0.7.5 fails on SONAR -->
91-
<version>0.7.4.201502262128</version>
95+
<version>0.7.5.201505241946</version>
9296
<executions>
9397
<execution>
9498
<id>jacoco-initialize</id>
@@ -99,7 +103,54 @@
99103
</execution>
100104
<execution>
101105
<id>jacoco-site</id>
102-
<phase>verify</phase>
106+
<phase>post-integration-test</phase>
107+
<goals>
108+
<goal>report</goal>
109+
<goal>report-integration</goal>
110+
</goals>
111+
</execution>
112+
</executions>
113+
<configuration>
114+
<includes>
115+
<include>pl/wavesoftware/**</include>
116+
</includes>
117+
</configuration>
118+
</plugin>
119+
</plugins>
120+
</build>
121+
</profile>
122+
123+
<profile>
124+
<id>sonar</id>
125+
<activation>
126+
<property>
127+
<!-- tries to determine is interactive user session -->
128+
<name>env.GDMSESSION</name>
129+
</property>
130+
</activation>
131+
<properties>
132+
<sonar.analysis.mode>preview</sonar.analysis.mode>
133+
<sonar.issuesReport.console.enable>true</sonar.issuesReport.console.enable>
134+
<sonar.issuesReport.html.enable>true</sonar.issuesReport.html.enable>
135+
<sonar.report.export.path>issues.json</sonar.report.export.path>
136+
</properties>
137+
<build>
138+
<plugins>
139+
<plugin>
140+
<groupId>org.jacoco</groupId>
141+
<artifactId>jacoco-maven-plugin</artifactId>
142+
<version>0.7.5.201505241946</version>
143+
<executions>
144+
<execution>
145+
<id>jacoco-initialize</id>
146+
<goals>
147+
<goal>prepare-agent</goal>
148+
<goal>prepare-agent-integration</goal>
149+
</goals>
150+
</execution>
151+
<execution>
152+
<id>jacoco-site</id>
153+
<phase>post-integration-test</phase>
103154
<goals>
104155
<goal>report</goal>
105156
<goal>report-integration</goal>
@@ -112,6 +163,48 @@
112163
</includes>
113164
</configuration>
114165
</plugin>
166+
167+
<plugin>
168+
<groupId>org.codehaus.mojo</groupId>
169+
<artifactId>sonar-maven-plugin</artifactId>
170+
<executions>
171+
<execution>
172+
<id>default</id>
173+
<phase>post-integration-test</phase>
174+
<goals>
175+
<goal>sonar</goal>
176+
</goals>
177+
</execution>
178+
</executions>
179+
</plugin>
180+
181+
<plugin>
182+
<groupId>org.codehaus.gmaven</groupId>
183+
<artifactId>groovy-maven-plugin</artifactId>
184+
<version>2.0</version>
185+
<dependencies>
186+
<dependency>
187+
<groupId>org.codehaus.groovy</groupId>
188+
<artifactId>groovy-all</artifactId>
189+
<version>2.0.6</version>
190+
</dependency>
191+
</dependencies>
192+
<configuration>
193+
<defaults>
194+
<sonar.issues.file>${sonar.working.directory}/${sonar.report.export.path}</sonar.issues.file>
195+
</defaults>
196+
<source>${project.basedir}/src/test/groovy/verify-sonar-issues.groovy</source>
197+
</configuration>
198+
<executions>
199+
<execution>
200+
<id>verify-sonar-issues</id>
201+
<phase>verify</phase>
202+
<goals>
203+
<goal>execute</goal>
204+
</goals>
205+
</execution>
206+
</executions>
207+
</plugin>
115208
</plugins>
116209
</build>
117210
</profile>
@@ -155,6 +248,7 @@
155248
<configuration>
156249
<compilerArgs>
157250
<arg>-Werror</arg>
251+
<arg>-Xlint:-deprecation</arg>
158252
<arg>-Xlint:all</arg>
159253
</compilerArgs>
160254
</configuration>
@@ -172,7 +266,7 @@
172266
<plugin>
173267
<groupId>org.apache.maven.plugins</groupId>
174268
<artifactId>maven-surefire-plugin</artifactId>
175-
<version>2.18.1</version>
269+
<version>2.19</version>
176270
<configuration>
177271
<trimStackTrace>false</trimStackTrace>
178272
</configuration>
@@ -181,7 +275,7 @@
181275
<plugin>
182276
<groupId>org.apache.maven.plugins</groupId>
183277
<artifactId>maven-failsafe-plugin</artifactId>
184-
<version>2.18.1</version>
278+
<version>2.19</version>
185279
<configuration>
186280
<trimStackTrace>false</trimStackTrace>
187281
<encoding>UTF-8</encoding>
@@ -196,6 +290,16 @@
196290
</executions>
197291
</plugin>
198292
</plugins>
293+
294+
<pluginManagement>
295+
<plugins>
296+
<plugin>
297+
<groupId>org.codehaus.mojo</groupId>
298+
<artifactId>sonar-maven-plugin</artifactId>
299+
<version>2.7.1</version>
300+
</plugin>
301+
</plugins>
302+
</pluginManagement>
199303
</build>
200304

201-
</project>
305+
</project>

src/main/java/pl/wavesoftware/eid/exceptions/Eid.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
*/
1616
package pl.wavesoftware.eid.exceptions;
1717

18+
import javax.annotation.Nonnull;
19+
import javax.annotation.Nullable;
1820
import java.io.Serializable;
19-
import static java.lang.Math.abs;
2021
import java.util.ArrayList;
2122
import java.util.List;
2223
import java.util.Random;
23-
import javax.annotation.Nullable;
24+
25+
import static java.lang.Math.abs;
2426

2527
/**
2628
* <strong>This class shouldn't be used in any public API or library.</strong> It is designed to be used for in-house development
@@ -93,7 +95,6 @@ public Eid(String id) {
9395
* @throws IllegalArgumentException if given format hasn't got two format specifiers <tt>"%s"</tt>, or if given format was
9496
* null
9597
*/
96-
@SuppressWarnings("UnusedReturnValue")
9798
public static String setMessageFormat(String format) {
9899
validateFormat(format, MESSAGE_FORMAT_NUM_SPEC);
99100
String oldFormat = Eid.messageFormat;
@@ -157,6 +158,23 @@ public static String setRefFormat(String refFormat) {
157158
return previously;
158159
}
159160

161+
/**
162+
* Makes a log message from this EID object
163+
* <p>
164+
* <p>This method is for convenience of usage of EID in logging. You can use it like this:
165+
* <p>
166+
* <pre>
167+
* log.debug(new Eid("20151025:202129").makeLogMessage("A request: %s", request));
168+
* </pre>
169+
* @param logMessageFormat a log message format as accepted by {@link String#format(String, Object...)}
170+
* @param parameters a parameters for logMessageFormat to by passed to {@link String#format(String, Object...)}
171+
* @return a formatted message
172+
*/
173+
public String makeLogMessage(@Nonnull String logMessageFormat, @Nonnull Object... parameters) {
174+
String message = String.format(logMessageFormat, parameters);
175+
return String.format(getMessageFormat(), this.toString(), message);
176+
}
177+
160178
@Override
161179
public String toString() {
162180
if ("".equals(ref)) {
@@ -238,11 +256,10 @@ public String generateUniqId() {
238256
long first = abs(random.nextLong() + 1);
239257
int second = abs(random.nextInt(Integer.MAX_VALUE));
240258
int calc = (int) (first + second);
241-
return Integer.toString(calc, BASE36);
259+
return Integer.toString(abs(calc), BASE36);
242260
}
243261

244-
@SuppressWarnings("squid:S2245")
245-
private Random getUnsecuredFastRandom() {
262+
private static Random getUnsecuredFastRandom() {
246263
return new Random(System.currentTimeMillis());
247264
}
248265

src/main/java/pl/wavesoftware/eid/exceptions/EidContainer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
*
2121
* @author Krzysztof Suszyński <[email protected]>
2222
*/
23-
@SuppressWarnings("WeakerAccess")
2423
public interface EidContainer {
2524

2625
/**

0 commit comments

Comments
 (0)