Skip to content

Commit 046d662

Browse files
committed
JAVA-757: Adding a new MongoException subclass called WriteConcernException, which DuplicateKey now extends. WriteConcernException takes the command result and passes toString() of it to MongoException, so the JSON representation of the entire document will appear in logs, instead of just the "err" field
1 parent 1c632bc commit 046d662

File tree

10 files changed

+86
-67
lines changed

10 files changed

+86
-67
lines changed

src/main/com/mongodb/CommandResult.java

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,9 @@
2525
public class CommandResult extends BasicDBObject {
2626

2727
CommandResult(ServerAddress srv) {
28-
this(null, srv);
29-
}
30-
31-
CommandResult(DBObject cmd, ServerAddress srv) {
3228
if (srv == null) {
3329
throw new IllegalArgumentException("server address is null");
3430
}
35-
_cmd = cmd;
3631
_host = srv;
3732
//so it is shown in toString/debug
3833
put("serverUsed", srv.toString());
@@ -61,55 +56,36 @@ public boolean ok(){
6156
* @return The error message or null
6257
*/
6358
public String getErrorMessage(){
64-
Object foo = get( "errmsg" );
65-
if ( foo == null )
59+
Object errorMessage = get( "errmsg" );
60+
if ( errorMessage == null )
6661
return null;
67-
return foo.toString();
62+
return errorMessage.toString();
6863
}
6964

7065
/**
7166
* utility method to create an exception with the command name
7267
* @return The mongo exception or null
7368
*/
74-
public MongoException getException(){
75-
if ( !ok() ) {
76-
StringBuilder buf = new StringBuilder();
77-
78-
String cmdName;
79-
if (_cmd != null) {
80-
cmdName = _cmd.keySet().iterator().next();
81-
buf.append( "command failed [" ).append( cmdName ).append( "]: " );
82-
} else {
83-
buf.append( "operation failed: ");
69+
public MongoException getException() {
70+
if ( !ok() ) { // check for command failure
71+
return new CommandFailureException( this );
72+
} else if ( hasErr() ) { // check for errors reported by getlasterror command
73+
if (getCode() == 11000 || getCode() == 11001 || getCode() == 12582) {
74+
return new MongoException.DuplicateKey(this);
8475
}
85-
86-
buf.append( toString() );
87-
88-
return new CommandFailure( this , buf.toString() );
89-
} else {
90-
// GLE check
91-
if ( hasErr() ) {
92-
Object foo = get( "err" );
93-
94-
int code = getCode();
95-
96-
String s = foo.toString();
97-
if ( code == 11000 || code == 11001 || s.startsWith( "E11000" ) || s.startsWith( "E11001" ) )
98-
return new MongoException.DuplicateKey( code , s );
99-
100-
return new MongoException( code , s );
76+
else {
77+
return new MongoException.WriteConcernException(this);
10178
}
10279
}
10380

104-
//all good, should never get here.
105-
return null;
81+
throw new IllegalStateException("This method should not be called if there is no exception");
10682
}
10783

10884
/**
10985
* returns the "code" field, as an int
11086
* @return -1 if there is no code
11187
*/
112-
int getCode(){
88+
int getCode() {
11389
int code = -1;
11490
if ( get( "code" ) instanceof Number )
11591
code = ((Number)get("code")).intValue();
@@ -139,20 +115,24 @@ public ServerAddress getServerUsed() {
139115
return _host;
140116
}
141117

142-
private final DBObject _cmd;
143118
private final ServerAddress _host;
144119
private static final long serialVersionUID = 1L;
145120

146-
static class CommandFailure extends MongoException {
121+
static class CommandFailureException extends MongoException {
147122
private static final long serialVersionUID = 1L;
123+
private final CommandResult commandResult;
148124

149125
/**
150126
*
151-
* @param res the result
152-
* @param msg the message
127+
* @param commandResult the result
153128
*/
154-
public CommandFailure( CommandResult res , String msg ){
155-
super( ServerError.getCode( res ) , msg );
129+
public CommandFailureException(CommandResult commandResult){
130+
super(ServerError.getCode(commandResult), commandResult.toString());
131+
this.commandResult = commandResult;
132+
}
133+
134+
public CommandResult getCommandResult() {
135+
return commandResult;
156136
}
157137
}
158138
}

src/main/com/mongodb/DB.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ public CommandResult command( DBObject cmd , int options, ReadPreference readPre
266266

267267
DBObject res = i.next();
268268
ServerAddress sa = (i instanceof Result) ? ((Result) i).getServerAddress() : null;
269-
CommandResult cr = new CommandResult(cmd, sa);
269+
CommandResult cr = new CommandResult(sa);
270270
cr.putAll( res );
271271
return cr;
272272
}
@@ -629,20 +629,20 @@ private CommandResultPair authenticateCommandHelper(String username, char[] pass
629629
try {
630630
authenticationTestCommandResult = doAuthenticate(credentials);
631631
return new CommandResultPair(authenticationTestCommandResult);
632-
} catch (CommandResult.CommandFailure commandFailure) {
633-
return new CommandResultPair(commandFailure);
632+
} catch (CommandResult.CommandFailureException commandFailureException) {
633+
return new CommandResultPair(commandFailureException);
634634
}
635635
}
636636

637637
class CommandResultPair {
638638
CommandResult result;
639-
CommandResult.CommandFailure failure;
639+
CommandResult.CommandFailureException failure;
640640

641641
public CommandResultPair(final CommandResult result) {
642642
this.result = result;
643643
}
644644

645-
public CommandResultPair(final CommandResult.CommandFailure failure) {
645+
public CommandResultPair(final CommandResult.CommandFailureException failure) {
646646
this.failure = failure;
647647
}
648648
}

src/main/com/mongodb/DBConnector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public Response call( DB db , DBCollection coll , OutMessage m ,
109109
*
110110
* @param credentials the credentials.
111111
* @return the result of the authentication command, if successful
112-
* @throws com.mongodb.CommandResult.CommandFailure if the authentication failed
112+
* @throws com.mongodb.CommandResult.CommandFailureException if the authentication failed
113113
* @since 2.11.0
114114
*/
115115
public CommandResult authenticate(MongoCredential credentials);

src/main/com/mongodb/DBPort.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ private CommandResult convertToCommandResult(DBObject cmd, Response res) {
177177
if ( data == null )
178178
throw new MongoInternalException( "something is wrong, no command result" );
179179

180-
CommandResult cr = new CommandResult(cmd, res.serverUsed());
180+
CommandResult cr = new CommandResult(res.serverUsed());
181181
cr.putAll( data );
182182
return cr;
183183
}

src/main/com/mongodb/MongoException.java

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,19 +119,38 @@ public Network( java.io.IOException ioe ){
119119
}
120120

121121
/**
122-
* Subclass of MongoException representing a duplicate key exception
122+
* An exception representing an error reported due to a write failure.
123123
*/
124-
public static class DuplicateKey extends MongoException {
124+
public static class WriteConcernException extends MongoException {
125125

126-
private static final long serialVersionUID = -4415279469780082174L;
126+
private static final long serialVersionUID = 841056799207039974L;
127+
128+
private final CommandResult commandResult;
129+
130+
public WriteConcernException(final CommandResult commandResult) {
131+
super(commandResult.getCode(), commandResult.toString());
132+
this.commandResult = commandResult;
133+
}
127134

128135
/**
129-
*
130-
* @param code the error code
131-
* @param msg the message
136+
* Gets the getlasterror command result document.
137+
*
138+
* @return the command result
132139
*/
133-
public DuplicateKey( int code , String msg ){
134-
super( code , msg );
140+
public CommandResult getCommandResult() {
141+
return commandResult;
142+
}
143+
}
144+
145+
/**
146+
* Subclass of WriteConcernException representing a duplicate key error
147+
*/
148+
public static class DuplicateKey extends WriteConcernException {
149+
150+
private static final long serialVersionUID = -4415279469780082174L;
151+
152+
public DuplicateKey(final CommandResult commandResult) {
153+
super(commandResult);
135154
}
136155
}
137156

src/test/com/mongodb/CommandResultTest.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,29 @@
2323

2424
public class CommandResultTest extends TestCase {
2525
@Test
26-
public void testNullCommand() throws UnknownHostException {
27-
CommandResult commandResult = new CommandResult(null, new ServerAddress("localhost"));
26+
public void testNullErrorCode() throws UnknownHostException {
27+
CommandResult commandResult = new CommandResult(new ServerAddress("localhost"));
2828
commandResult.put("ok", 0);
29-
MongoException e = commandResult.getException();
30-
assertNotNull(e);
31-
assert(e instanceof CommandResult.CommandFailure);
32-
assertEquals(-5, e.getCode());
29+
try {
30+
commandResult.throwOnError();
31+
fail("Should throw");
32+
} catch (CommandResult.CommandFailureException e) {
33+
assertEquals(commandResult, e.getCommandResult());
34+
assertEquals(-5, e.getCode());
35+
}
36+
}
37+
38+
@Test
39+
public void testCommandFailure() throws UnknownHostException {
40+
CommandResult commandResult = new CommandResult(new ServerAddress("localhost"));
41+
final DBObject result = new BasicDBObject("ok", 0.0).append("errmsg", "no not found").append("code", 5000);
42+
commandResult.putAll(result);
43+
try {
44+
commandResult.throwOnError();
45+
fail("Should throw");
46+
} catch (CommandResult.CommandFailureException e) {
47+
assertEquals(commandResult, e.getCommandResult());
48+
assertEquals(5000, e.getCode());
49+
}
3350
}
3451
}

src/test/com/mongodb/DBCollectionTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ public void testDuplicateKeyException() {
7676
Assert.fail();
7777
}
7878
catch (MongoException.DuplicateKey e) {
79-
// Proves that a DuplicateKey exception is thrown, as test will fail if any other exception is thrown
79+
assertNotNull(e.getCommandResult());
80+
assertEquals(11000, e.getCode());
8081
}
8182
}
8283

src/test/com/mongodb/DBPortTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public void testAuthentication() throws IOException {
5858
try {
5959
port.checkAuth(m);
6060
fail("should throw");
61-
} catch (CommandResult.CommandFailure e) {
61+
} catch (CommandResult.CommandFailureException e) {
6262
// all good
6363
}
6464
}

src/test/com/mongodb/DBTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ public void testEnsureConnection() throws UnknownHostException {
144144
}
145145
}
146146

147+
148+
147149
/*public static class Person extends DBObject {
148150
149151
public Person(){

src/test/com/mongodb/JavaClientTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ public void testAuthenticateCommand() throws UnknownHostException {
694694
try {
695695
db.authenticateCommand( "xx" , "f".toCharArray());
696696
fail("Auth should have failed");
697-
} catch (CommandResult.CommandFailure e) {
697+
} catch (CommandResult.CommandFailureException e) {
698698
// all good
699699
}
700700
assertTrue(db.authenticateCommand("xx", "e".toCharArray()).ok());

0 commit comments

Comments
 (0)