I have a list with domains. When I iterate over this list I get domains mx records. If the domain is invalid try catch block throws NamingException and iterating over the list stops. How to continue program execution after throwing a name exception ?
try {
logger(clazz, "job started");
List<Domain> domains = new ArrayList<>();
domains.addAll(domManager.getActiveDoms());
for (Domain d : domains) {
Attributes attributes = iDirC.getAttributes("dns:/" + d.getName(), new String[] { "MX" });
Attribute attributeMX = attributes.get("MX");
System.out.println(attributes);
}
} catch (NamingException e) {
e.printStackTrace();
}
Your code has an try-catch block with a loop inside it, that way, if something fails, the program will abort (because of e.printStackTrace()).
Note that you said "(...) after throwing a name exception" and that is not what is happening! In order to throw an exception, you have to use throw new NamingException("cause"); and have a throws NamingException in your method's declaration.
Now, answering your question:
If you handle the error inside the loop, you can continue (note that if you have e.printStackTrace() the program will still end there).
I would do something like:
logger(clazz, "job started");
List<Domain> domains = new ArrayList<>();
domains.addAll(domManager.getActiveDoms());
for (Domain d : domains) {
try {
Attributes attributes = iDirC.getAttributes("dns:/" + d.getName(), new String[] { "MX" });
Attribute attributeMX = attributes.get("MX");
System.out.println(attributes);
} catch (NamingException e) {
//do somethig here like `System.out.println("error message!");`
}
}
Hope this helps you!
Related
Inside a method, a condition is needed to proceed the logic. An unhandled exception warning message shows up in my IDE. Wrapping the whole block with try-catch doesn't let the message go away.
public void changePassword(String login, String currentClearTextPassword, String newPassword) {
userRepository.findOneByLogin(login)
.ifPresent(user -> {
String currentEncryptedPassword = user.getUserSecret();
String encryptedInputPassword = "";
try {
encryptedInputPassword = authUtils.encrypt(currentClearTextPassword);
} catch (Exception ex) {
System.err.println("Encryption exception: " + ex.getMessage());
}
if (!Objects.equals(encryptedInputPassword, currentEncryptedPassword)) {
throw new Exception("Invalid Password"); // <-- unhandled exception
}
String encryptedNewPassword = "";
try {
encryptedNewPassword = authUtils.encrypt(newPassword);
} catch (Exception ex) {
System.err.println("Encryption exception: " + ex.getMessage());
}
user.setUserSecret(encryptedNewPassword);
userRepository.save(user);
log.debug("Changed password for User: {}", user);
});
}
How to deal with this warning message?
Treating Exception inside stream operation is a little overhead, I would like to separate the operation and makes it like so :
public void changePassword(String login, String currentClearTextPassword, String newPassword) throws Exception {
//get the user in Optional
Optional<User> check = userRepository.findOneByLogin(login);
//if the user is present 'isPresent()'
if(check.isPresent()){
//get the user from the Optional and do your actions
User user = check.get();
String currentEncryptedPassword = user.getUserSecret();
String encryptedInputPassword = "";
try {
encryptedInputPassword = authUtils.encrypt(currentClearTextPassword);
} catch (Exception ex) {
throw new Exception("Encryption exception: " + ex.getMessage());
}
if (!Objects.equals(encryptedInputPassword, currentEncryptedPassword)) {
throw new Exception("Invalid Password"); // <-- unhandled exception
}
String encryptedNewPassword = "";
try {
encryptedNewPassword = authUtils.encrypt(newPassword);
} catch (Exception ex) {
throw new Exception("Encryption exception: " + ex.getMessage());
}
user.setUserSecret(encryptedNewPassword);
userRepository.save(user);
log.debug("Changed password for User: {}", user);
}
}
Beside the Exception should be thrown not just printed.
Like #louis-wasserman said you can use an unchecked exception.
So instead of
throw new Exception("Invalid Password");
use:
throw new RuntimeException("Invalid Password"); // for example
Note: It is better to use a custom RuntimeException that fits your use case.
For the general case, #pari-ngang is correct: within a lambda expression you cannot handle a checked exception outside the calling function. Either use an unchecked or use the try construct in the lambda.
However, needing to do either of these might be a sign of poor structure. Having a large block of code within a lambda is one such sign. Here are a few suggestions for your specific case:
1. As a simplification of #ycf-l's answer, invert the logic and simply return user if not found:
Optional<User> user = userRepository.findOneByLogin(login);
if (!user.isPresent()) {
return;
}
// ... carry on as before outside of a lambda
2. Seperate the logic of fetching the user from changing the password of a user (you'll still have to pass exceptions back up):
if (user.isPresent()) {
changePassword(user.get(), currentClearTextPassword, newPassword);
}
3. You can also use libraries like vavr to simplify the try/catch blocks:
String encryptedInputPassword = Try.of(() -> authUtils.encrypt(currentClearTextPassword))
.onFailure(e -> System.err.println("Encryption exception: " + e.getMessage()))
.orElse("");
4. If you're willing to pursue vavr, you can also solve the more general problem:
userRepository.findOneByLogin(login)
.map(user -> Try.of(() -> {
// Your change password stuff goes here.
changePassword(user, currentClearTextPassword, newPassword);
return null; // I don't currently know of any way of passing a runnable.
}))
// This pulls the exception out of the lambda function, satisfying the compiler.
.orElseGet(() -> Try.success(null))
.getOrElseThrow(Function.identity());
I haven't used vavr much so can't tell you if this is the most efficient/cleanest approach/use of vavr, but it will solve your problem.
I am new to JUnit and I have to test a method using JUnit api. One method internall calls another. My test case goes inside the method but while catchign the exception it fails.
Method under test is
public void checkANDCondition( Map<String, Message> messagesMap ) throws EISClientException
{
List<String> codes = getMessageCodes();
if(isAllReturnedMessagesContainCodes(codes, messagesMap))
{
StringBuffer buff = new StringBuffer("All of the specified message codes matched returned errors.");
for(String code: codes )
{
Message message = messagesMap.get(code);
buff.append(message.getMessageCode() + ": " + message.getMessageType() + ": " + message.getMessageText() + " ");
}
throw new EISClientException(buff.toString());
}
}
public boolean isAllReturnedMessagesContainCodes(List<String> codes, Map<String, Message> messagesMap)
{
if(codes!=null)
{
for(String code: codes)
{
if(!messagesMap.containsKey(code))
{
return false;
}
}
}
return true;
}
What I have done so far is
#Test
public void testPostProcess() throws Exception {
clientResponse = mock(ClientResponse.class);
MessageToExceptionPostProcessFilter postProcessFilter = new MessageToExceptionPostProcessFilter();
RetrieveBillingServiceResponse serviceResponse = new RetrieveBillingServiceResponse();caughtException = false;
try {
postProcessFilter.setCondition(ConditionOperator.AND);
List<String> messagesCodes = new ArrayList<String>();
messagesCodes.add("200");
messagesCodes.add("400");
Message message = new Message();
message.setMessageCode("200");
message.setMessageType(MessageTypeEnum.MESSAGE_TYPE_INFO);
message.setMessageText("Service completed successfully");
serviceResponse.setMessages(Arrays.asList(message));
postProcessFilter.setMessageCodes(messagesCodes);
serviceResponse = postProcessFilter.postProcess(serviceResponse, clientResponse);
assertNotNull(serviceResponse.getMessages());
} catch (EISClientException ex) {
caughtException = true;
assertEquals("All of the specified message codes matched returned errors.", ex.getMessage());
}
assertTrue(caughtException);
}
How can I make it pass?
Thanks
#Test(expected = EISCLientException.class)
public void testPostProcess() throws Exception {
...
serviceResponse.getMessages();
fail("Shouldn't reach this point");
}
That way you don't need to catch, with expected if it does not get throw a EISClientException it will fail.
edit: There are two times I can think of where you wouldn't want to use this.
1) You are mocking exceptions that are thrown mock(exception.class);
this i believe then throws some Mockito excpetion and it will not match the expected exception.
2) You are wrapping caught exceptions in your code, and throwing a generic exception. Example of code:
try {
} catch (FileParseException e){
throw new (ProjectFailingException(e, "file is bad");
}
if you have multiple catches and are wrapping them as ProjectFailingExceptions then you may want to catch in the test like this...
#Test ( expected = FileParseException.class)
public void testProcess() {
try {
...
} catch (ProjectFailingException e){
throw e.getCause();
}
Then the proper exception is thrown and you can make sure that process isn't throwing an exception from a a different catch.
I am calling a method from a third party jars whose class file is not accessible to me. So for some cases it throws exception logs and I want to extract string from the current log dynamically.
This is the java program method which throws exception
public String runLayoutTest(final String xmlFile){
try{
String gettingValue = "novalue";
boolean errorFlag = perform("runLayoutTest", new Reporter.Reportable() {
#Override
public boolean run() throws Exception {
String layoutXml = null;
//current directory
Path currentRelativePath = Paths.get("");
String currentProjectPath = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + currentProjectPath);
System.out.println("layoutXml "+xmlFile);
String x = client.runLayoutTest(currentProjectPath+"\\Excel\\"+xmlFile);
System.out.println("******* x ********"+x);
setX(x);
return true;
}
});
gettingValue = getX();
return gettingValue;
}catch(Exception e){
System.out.println("**Any one rule in Layout is failed**");
//System.out.println(e.getMessage());
return getX();
}
}
Here the client is a object of the third party jar file , And that is throwing me the exception on some odd cases .
The Exception logs are
com.experitest.client.InternalException: Exception caught while executing runLayoutTest: {"rule_1":{"Exists":true},"rule_2":{"Exists":true,"EqualHeight":false},"rule_3":{"AlignedLeft":false}}
at com.experitest.client.JavaClientInternals.executeInternally(JavaClientInternals.java:234)
at com.experitest.client.Client.execute(Client.java:237)
at com.experitest.client.Client.runLayoutTest(Client.java:1475)
at com.igate.framework.NativeDriver$79.run(NativeDriver.java:2753)
at com.igate.framework.Reporter.action(Reporter.java:81)........
From this exception I want to extract
runLayoutTest: {"rule_1":{"Exists":true},"rule_2":{"Exists":true,"EqualHeight":false},"rule_3":{"AlignedLeft":false}}
as a String.
Hence is there any method with which I can dynamically extract such String whenever it occurs.
And I still don't know the reason why my catch method is not getting called.
In your case you can just use Exception.getMessage() which will result in
Exception caught while executing runLayoutTest:
{"rule_1":{"Exists":true},"rule_2":{"Exists":true,"EqualHeight":false},"rule_3":{"AlignedLeft":false}}
Below can be used to get the json string. You can then parse the json to get desired data from it
String message = e.getMessage();
int colonIndex = message.indexOf(":");
String json = null;
if (colonIndex != -1) {
json = message.substring(colonIndex + 1);
}
Please note that this solution will not work in case of wrapped exception
I had to implement this code to attack directly to throwable detailMessage. I had to ignore all the hierarchy of classes that extended Exception because someone implemented a horrible getMessage method that was being overlapped with web components. In JUnit was no way to define unit test cases because framework's exceptions always tried to translate its error code into the 'session' (web) language...
public static Object getThrowableDetailMessage(Throwable throwable) {
try {
// Tiramos la puerta abajo y pedimos a Throwable que nos pase el código de error
Field f = Throwable.class.getDeclaredField("detailMessage");
f.setAccessible(true);
Object detailMessageFound = f.get(throwable);
return detailMessageFound;
} catch (SecurityException ex) {
//LOG
return null;
} catch (NoSuchFieldException e) {
//LOG
return null;
} catch (IllegalArgumentException e) {
//LOG
return null;
} catch (IllegalAccessException e) {
//LOG
return null;
}
}
You also can try to replace Throwable by InternalException and keep the reflection on this level of the hierachy. But like someone is already pointing. Make sure your code is being affected by the Exception you want to inspect.
I have implemented all the catches possible because I wanted to trace a different log for everyone of them. (For debugging and testing overall)
Note: My code has been implemented under JDK 1.6_18
I have to send a set of files to several computers through a certain port. The fact is that, each time that the method that sends the files is called, the destination data (address and port) is calculated. Therefore, using a loop that creates a thread for each method call, and surround the method call with a try-catch statement for a BindException to process the situation of the program trying to use a port which is already in use (different destination addresses may receive the message through the same port) telling the thread to wait some seconds and then restart to retry, and keep trying until the exception is not thrown (the shipping is successfully performed).
I didn't know why (although I could guess it when I first saw it), Netbeans warned me about that sleeping a Thread object inside a loop is not the best choice. Then I googled a bit for further information and found this link to another stackoverflow post, which looked so interesting (I had never heard of the ThreadPoolExecutor class). I've been reading both that link and the API in order to try to improve my program, but I'm not yet pretty sure about how am I supposed to apply that in my program. Could anybody give a helping hand on this please?
EDIT: The important code:
for (Iterator<String> it = ConnectionsPanel.list.getSelectedValuesList().iterator(); it.hasNext();) {
final String x = it.next();
new Thread() {
#Override
public void run() {
ConnectionsPanel.singleAddVideos(x);
}
}.start();
}
private static void singleAddVideos(String connName) {
String newVideosInfo = "";
for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
newVideosInfo = newVideosInfo.concat(it.next().toString());
}
try {
MassiveDesktopClient.sendMessage("hi", connName);
if (MassiveDesktopClient.receiveMessage(connName).matches("hello")) {
MassiveDesktopClient.sendMessage(newVideosInfo, connName);
}
} catch (BindException ex) {
MassiveDesktopClient.println("Attempted to use a port which is already being used. Waiting and retrying...", new Exception().getStackTrace()[0].getLineNumber());
try {
Thread.sleep(MassiveDesktopClient.PORT_BUSY_DELAY_SECONDS * 1000);
} catch (InterruptedException ex1) {
JOptionPane.showMessageDialog(null, ex1.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
ConnectionsPanel.singleAddVideos(connName);
return;
}
for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
try {
MassiveDesktopClient.sendFile(it.next().getAttribute("name"), connName);
} catch (BindException ex) {
MassiveDesktopClient.println("Attempted to use a port which is already being used. Waiting and retrying...", new Exception().getStackTrace()[0].getLineNumber());
try {
Thread.sleep(MassiveDesktopClient.PORT_BUSY_DELAY_SECONDS * 1000);
} catch (InterruptedException ex1) {
JOptionPane.showMessageDialog(null, ex1.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
ConnectionsPanel.singleAddVideos(connName);
return;
}
}
}
Your question is not very clear - I understand that you want to rerun your task until it succeeds (no BindException). To do that, you could:
try to run your code without catching the exception
capture the exception from the future
reschedule the task a bit later if it fails
A simplified code would be as below - add error messages and refine as needed:
public static void main(String[] args) throws Exception {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(corePoolSize);
final String x = "video";
Callable<Void> yourTask = new Callable<Void>() {
#Override
public Void call() throws BindException {
ConnectionsPanel.singleAddVideos(x);
return null;
}
};
Future f = scheduler.submit(yourTask);
boolean added = false; //it will retry until success
//you might use an int instead to retry
//n times only and avoid the risk of infinite loop
while (!added) {
try {
f.get();
added = true; //added set to true if no exception caught
} catch (ExecutionException e) {
if (e.getCause() instanceof BindException) {
scheduler.schedule(yourTask, 3, TimeUnit.SECONDS); //reschedule in 3 seconds
} else {
//another exception was thrown => handle it
}
}
}
}
public static class ConnectionsPanel {
private static void singleAddVideos(String connName) throws BindException {
String newVideosInfo = "";
for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
newVideosInfo = newVideosInfo.concat(it.next().toString());
}
MassiveDesktopClient.sendMessage("hi", connName);
if (MassiveDesktopClient.receiveMessage(connName).matches("hello")) {
MassiveDesktopClient.sendMessage(newVideosInfo, connName);
}
for (Iterator<Video> it = ConnectionsPanel.videosToSend.iterator(); it.hasNext();) {
MassiveDesktopClient.sendFile(it.next().getAttribute("name"), connName);
}
}
}
main method:
public static void main(String[] args) throws Exception
{
if (args.length != EXPECTED_NUMBER_OF_ARGUMENTS)
{
System.err.println("Usage - java XFRCompiler ConfigXML PackageXML XFR");
}
String configXML = args[0];
String packageXML = args[1];
String xfr = args[2];
AutoConfigCompiler compiler = new AutoConfigCompiler();
compiler.setConfigDocument(loadDocument(configXML));
compiler.setPackageInfoDoc(loadDocument(packageXML));
// compiler.setVisiblityDoc(loadDocument("VisibilityFilter.xml"));
compiler.compileModel(xfr);
}
private static Document loadDocument(String fileName) throws Exception
{
TXDOMParser parser = (TXDOMParser) ParserFactory.makeParser(TXDOMParser.class.getName());
InputSource source = new InputSource(new FileInputStream(fileName));
parser.parse(source);
return parser.getDocument();
}
testcase:
#Test
public void testCompileModel() throws Exception
{
// construct parameters
URL configFile = Thread.currentThread().getContextClassLoader().getResource("Ford_2008_Mustang_Config.xml");
URL packageFile = Thread.currentThread().getContextClassLoader().getResource("Ford_2008_Mustang_Package.xml");
File tmpFile = new File("Ford_2008_Mustang_tmp.xfr");
if(!tmpFile.exists()) {
tmpFile.createNewFile();
}
String[] args = new String[]{configFile.getPath(),packageFile.getPath(),tmpFile.getPath()};
try {
// test main method
XFRCompiler.main(args);
} catch (Exception e) {
assertTrue(true);
}
try {
// test args length is less than 3
XFRCompiler.main(new String[]{"",""});
} catch (Exception e) {
//ignore
}
tmpFile.delete();
}
Coverage outputs displayed as the lines from String configXML = args[0]; in main method
are not covered.
assertTrue(true); is a pointless no-op
Remove the try/catch around the call to XFRCompiler.main(args);, since all it does is swallow excpetions and make debugging harder; most likely you will then see an exception that tells you where the problem is.
There should be a call to fail() after the call to XFRCompiler.main(new String[]{"",""}); since you expect it to throw an exception
Put the two calls in separate test methods.
I'm worried about all those assertTrue(true). If there can't be an exception, then the assert is not necessary. If there is an unexpected exception, then this code will swallow it and you will get the behavior you see right now.
Then, if you expect an exception, you should code like this:
try {
... code that will throw an exception ...
fail("No exception was thrown");
} catch (SpecficTypeOfException e) {
assertEquals("message", e.getMessage());
}
That way, wrong types of exception and the exception message will be checked.
PS: Don't post questions with "urgent". We already help as fast as we can.