Skip to content

Commit 5579e8d

Browse files
committed
Update SolverException to use String.format
MessageFormat cannot show Double.MIN_VALUE or Double.MIN_NORMAL. These are represented as 0. Changing to String.format fixes this. This was discovered from convergence errors involving sub-normal numbers that have no useful information in the exception message (as the numbers are zero).
1 parent d8a2011 commit 5579e8d

File tree

2 files changed

+67
-7
lines changed

2 files changed

+67
-7
lines changed

commons-numbers-rootfinder/src/main/java/org/apache/commons/numbers/rootfinder/SolverException.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,29 @@
1616
*/
1717
package org.apache.commons.numbers.rootfinder;
1818

19-
import java.text.MessageFormat;
20-
2119
/**
2220
* Package private exception class with constants for frequently used messages.
2321
*/
2422
class SolverException extends IllegalArgumentException {
2523
/** Error message for "too large" condition. */
26-
static final String TOO_LARGE = "{0} > {1}";
24+
static final String TOO_LARGE = "%s > %s";
2725
/** Error message for "out of range" condition. */
28-
static final String OUT_OF_RANGE = "{0} is out of range [{1}, {2}]";
26+
static final String OUT_OF_RANGE = "%s is out of range [%s, %s]";
2927
/** Error message for "failed bracketing" condition. */
30-
static final String BRACKETING = "No bracketing: f({0})={1}, f({2})={3}";
28+
static final String BRACKETING = "No bracketing: f(%s)=%s, f(%s)=%s";
3129

3230
/** Serializable version identifier. */
3331
private static final long serialVersionUID = 20190602L;
3432

3533
/**
3634
* Create an exception where the message is constructed by applying
37-
* the {@code format()} method from {@code java.text.MessageFormat}.
35+
* the {@code format()} method from {@code String}.
3836
*
3937
* @param message the exception message with replaceable parameters
4038
* @param formatArguments the arguments for formatting the message
39+
* @see String#format(String, Object...)
4140
*/
4241
SolverException(String message, Object... formatArguments) {
43-
super(MessageFormat.format(message, formatArguments));
42+
super(String.format(message, formatArguments));
4443
}
4544
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.numbers.rootfinder;
18+
19+
import org.junit.jupiter.api.Assertions;
20+
import org.junit.jupiter.api.Test;
21+
22+
/**
23+
* Test cases for the {@link SolverException} class.
24+
*/
25+
class SolverExceptionTest {
26+
@Test
27+
void testOutOfRangeFormatting() {
28+
final double x = Double.MIN_NORMAL;
29+
final double y = Double.MIN_VALUE;
30+
final double z = 1.0;
31+
final String msg = new SolverException(SolverException.OUT_OF_RANGE,
32+
x, y, z).getMessage();
33+
Assertions.assertTrue(msg.contains(String.valueOf(x)), () -> "Missing: " + x);
34+
Assertions.assertTrue(msg.contains(String.valueOf(y)), () -> "Missing: " + y);
35+
Assertions.assertTrue(msg.contains(String.valueOf(z)), () -> "Missing: " + z);
36+
}
37+
38+
@Test
39+
void testBracketingFormatting() {
40+
final double w = Double.MAX_VALUE;
41+
final double x = Double.MIN_NORMAL;
42+
final double y = Double.MIN_VALUE;
43+
final double z = 1.0;
44+
final String msg = new SolverException(SolverException.BRACKETING,
45+
w, x, y, z).getMessage();
46+
Assertions.assertTrue(msg.contains(String.valueOf(w)), () -> "Missing: " + w);
47+
Assertions.assertTrue(msg.contains(String.valueOf(x)), () -> "Missing: " + x);
48+
Assertions.assertTrue(msg.contains(String.valueOf(y)), () -> "Missing: " + y);
49+
Assertions.assertTrue(msg.contains(String.valueOf(z)), () -> "Missing: " + z);
50+
}
51+
52+
@Test
53+
void testTooLargeFormatting() {
54+
final double x = Double.MIN_NORMAL;
55+
final double y = Double.MIN_VALUE;
56+
final String msg = new SolverException(SolverException.TOO_LARGE,
57+
x, y).getMessage();
58+
Assertions.assertTrue(msg.contains(String.valueOf(x)), () -> "Missing: " + x);
59+
Assertions.assertTrue(msg.contains(String.valueOf(y)), () -> "Missing: " + y);
60+
}
61+
}

0 commit comments

Comments
 (0)