I was writing a method for TCPServer. I've written a code as below:
// thread run
protected void threadRun(){
// continue running. don't stop
while(true){
try{
try{
}
catch(Exception e1){
try{
} catch(Exception e2){}
finally{
// skip
continue;
}
}
}
catch(Exception e3){
}
}
}
Content is not important. There were codes to accept client etc, but I have removed them to make sure about that it is not about details. Anyway, when I try to compile this code, compiler says for that continue line:
Error: continue is not inside a loop
By thinking that maybe I know it wrong, I've written the complete same code in Java as seen below:
class test{
public static void main(String[] args){
while(true){
try{
try{
}
catch(Exception e1){
try{
} catch(Exception e2){}
finally{
continue;
}
}
}
catch(Exception e3){
}
}
}
}
As I expected, java compiler doesn't give any error message and compiles successfully. What exactly can the problem be?
Apparently, continue (and break) can't break out of a finally block. Compiling this:
void run() {
loop:
while (true) {
try {}
catch (Exception e) {}
finally {
continue loop;
}
}
}
will give you this (omitting the label gives the same error you got):
Error: cannot continue out of finally block
I haven't yet found a justification or explanation of this restriction (edit: see ratchet freak's comment below). However, I can't imagine it's a super-common use case. You probably want to look at other options.
Related
When I want just to add more context to any exception that has happened (including parsing errors and even out of memory) I write code as follows
try {
new JsonSlurper().parseText(response)
} catch (any) {
throw new IllegalStateException("Cannot parse response:\n$response", any)
}
This works fine, but I may end up with OutOfMemoryError being wrapped in IllegalStateException which doesn't sound right, as further there could be dedicated exception handling mechanism just for Error throwables.
Is there any way to just add more context to exception and still preserve its original type or category? I.e. when I get OOME, I want to rethrow Error, when I get some parsing exception, I want to rethrow some unchecked exception etc. And of course I don't want to do it manually for each category, as OOME is pretty unlikely and I don't want to produce special code for corner cases (while still I want to be technically correct).
You can definitely do this in groovy by using its metaprogramming features. In particular, for your case metaclasses provides everything you need. Using them you can dynamically add/attach a contextData object to the exception you want it to carry around:
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
Then to retrieve this contextData in other parts of the code, just inspect the exception object like this:
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
There I am using the argument contextDataHandler as a groovy Closure to handle contextData in a flexible manner.
The following is a full working demo of this:
import java.time.LocalDateTime
class ExceptionEnhancer {
static void main(String[] args) {
def logger = { println "${LocalDateTime.now()} - Context Data = [$it]" }
doSomethingWithContextData logger
}
private static void doSomethingWithContextData(Closure contextDataHandler) throws IOException {
try {
throwsEnhancedException();
} catch (IOException e) {
// RETRIEVE `contextData` FROM `e` OR NULL IF THE PROPERTY DO NOT EXIST
def contextData = e.hasProperty('contextData')?.getProperty(e)
// DO SOMETHING WITH `contextData`
contextDataHandler(contextData)
}
}
private static void throwsEnhancedException() throws IOException {
try {
throwsBasicException()
} catch (IOException e) {
e.metaClass.contextData = "My context data"
throw e;
}
}
public static void throwsBasicException() throws IOException {
throw new IOException();
}
}
Complete code on GitHub
Hope this helps.
I have some Prism work. Specifically, a bootstrapper (MefBootstrapper) that calls InitializeModules. During one of the modules, an exception is raised, when I re-throw this, I get an exception unhandled.
Unsuccessfully, I have added delegate methods to the exception events, like:
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
System.Windows.Application.Current.DispatcherUnhandledException += CurrentOnDispatcherUnhandledException;
First, you need to mark the exception as handled in the event handler attached to AppDomain.CurrentDomain.UnhandledException to keep the application from crashing:
Application.Current.Dispatcher.UnhandledException += (sender, e) => e.Handled = true;
Second, an exception thrown during a given Prism Module initialization can stop other Modules from loading. To circumvent this you can subclass ModuleManager as follows:
public class ErrorHandlingModuleManager : ModuleManager
{
public ErrorHandlingModuleManager(IModuleInitializer moduleInitializer, IModuleCatalog moduleCatalog, ILoggerFacade loggerFacade) : base(moduleInitializer, moduleCatalog, loggerFacade)
{
}
protected override void LoadModulesThatAreReadyForLoad()
{
var initializationExceptions = new List<Exception>();
while (true)
{
try
{
base.LoadModulesThatAreReadyForLoad();
break;
}
catch (ModuleInitializeException e)
{
initializationExceptions.Add(e);
}
catch (Exception e)
{
initializationExceptions.Add(e);
break;
}
}
if (initializationExceptions.Any())
throw new AggregateException(initializationExceptions);
}
}
}
Be sure to register ErrorHandlingModuleManager with your Mef container to override the the default.
Why we need multiple "catch" blocks even though we can write one generic
exception?
Is that important to know all the exception types and their purposes to make a good piece of code?
I googled a lot but still have confusions in exception handling. Any good example?
Generic Exception:
try{
//some code
}
catch(Exception e){
//print e
}
//that's it.
Multiple catches
try{
//some code
}
catch(IOException e){
}
catch(SQLException e){
}
There are several advantages of using multiple exceptions:
General exceptions will not let you know the exact root cause of the issue especially if many steps/checks involved in a method implementation. Also, If the exception occurs due to various reasons, you need to throw the different types of exceptions from your caller method implementation.
Eg: You can throw custom exceptions.
Here is your service code:
public void Login(string username, string password)
{
if(string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
{
throw InvalidUserNameException();
}
if(!IsInternetAvaialable())
{
throw NoInternetAvailableException()
}
else
{
//Implement though your login process and if need use various custom exceptions or throw the exception if occurs.
}
}
public class InvalidUserNameException : Exception
{
public InvalidUserNameException()
{
}
public InvalidUserNameException(string message)
: base(message)
{
}
public InvalidUserNameException(string message, Exception inner)
: base(message, inner)
{
}
}
Caller Method:
try {
...
} catch(InvalidUserNameException e) {
// Show Alert Message here
} catch(NoInternetAvaibleException e) {
// Show Alert Message with specific reason
}
catch(Exception e) {
// Other Generic Exception goes here
}
Reference:
https://learn.microsoft.com/en-us/dotnet/standard/exceptions/how-to-create-user-defined-exceptions
1. Why we need multiple "catch" blocks even though we can write one generic exception?
Sometimes you might need to specify what causes the problem.
For example,
try {
...
} catch(IOException e) {
// Print "Error: we cannot open your file"
} catch(SQLException e) {
// Print: "Error: we cannot connect to the database"
}
With different errors, users can understand what went wrong easily.
If we go with
try {
...
} catch(Exception e) {
// Print "Error: " + e.
}
It's harder for the users to figure out what went wrong.
Also, we can send the users to different pages accordingly to the error if we use multiple catch-es.
2.Is that important to know all the exception types and their purposes to make a good piece of code?
Personally, I would go with important exceptions such as IO, DB, etc. that can cause serious trouble. For others, I would catch with general exception.
I have a question , why does java keeps throwing that exception ! Is the problem with the stream ? because I handeled all IOExceptionS !
[[jio0yh.java:12: error: unreported exception IOException; must be
caught or declared to be thrown]]>>
That's the exception that I'm getting!
here is my code
import java.io.*;
public class jio0yh{
public static void main(String[]args){
FileInputStream OD=null;
try{
File f=new File("Binary.dat");
OD= new FileInputStream(f);
byte[]b=new byte[(int)f.length()];
OD.read(b);
for(int i=0;i<b.length;i++)
System.out.println(b[i]);
} catch(FileNotFoundException e){
System.out.println(e.getMessage());
} catch(IOException e){
System.out.println(e.getMessage());
OD.close();
}
}
}
The OD.close(); in your IOException catch block is also susceptible to throwing another IOException.
You should surround the final OD.close() in a finally block:
// ... Any previous try catch code
} finally {
if (OD != null) {
try {
OD.close();
} catch (IOException e) {
// ignore ... any significant errors should already have been
// reported via an IOException from the final flush.
}
}
}
Refer to the following for a more thorough explanation:
Java try/catch/finally best practices while acquiring/closing resources
Is there any language that supports something like the below construct, or is there a good way to achieve this using the ubiquitous try-catch-finally?
try
{
} catch(Exception1 e)
{ .... }
catch(Exception2 e)
{ .... }
catch-finally
{
//Perform action, such as logging
}
finally
{
//This always occurs but I only want to log when an exception occurs.
}
I understand this depends on the particular language, but is there some such support in Java, C#, C++, PHP etc?
Put a "global" try/catch in your main program or high-level method. This catches all exceptions that are not caught elsewhere.
try
{
// Main method, or higher level method call
}
catch (Exception ex)
{
// Log exception here
}
Then, in your subordinate try/catch clauses, just handle your exceptions in the usual way, and then rethrow. The rethrown exception will bubble up to your main try/catch and be logged.
try
{
// Do your thing
}
catch(SomeException ex)
{
// Handle exception here
// rethrow exception to logging handler
throw;
}
I don't think so as the behaviour you describe can be easily modelled as:
boolean success = false;
try {
...
success = true;
} catch (Exception_1 e) {
...
}
...
} catch (Exception_N e) {
...
} finally {
if (success) {
// your "finally"
} else {
// your "catch-finally"
}
}
You can easily accomplish that in C#. A simple way would be to save the exception in your catch blocks, then in your finally block, log if the exception object is not null.
Exception ex;
try
{
}
catch (ExceptionType1 type1)
{
ex = type1;
}
catch (ExceptionType2 type2)
{
ex = type2;
}
finally
{
if (ex != null)
{
//Log
}
}
Visual Basic has a construct that can be used for this. This isn't really "finally" in the sense of [almost] never failing to execute, but it'll support the case when you only want to log the exceptions that you're handling, and you have access to the exception object within the shared code. You've also got the flexibility of having the shared code execute before or after the individual exception type code.
Try
...
Catch ex As Exception When TypeOf(ex) Is Type1 OrElse TypeOf(ex) Is Type2
...
If TypeOf(ex) Is Type1 Then
...
ElseIf TypeOf(ex) Is Type2 Then
...
End If
End Try
Something like this, as long as the language has throw with no parameters to rethrow a caught exception:
try
{
} catch(Everything) {
try {
throw;
} catch (Exception1 e) {
....
} catch (Exception2 e) {
....
} finally {
//Perform action, such as logging
}
} finally {
//This always occurs but I only want to log when an exception occurs.
}
That's if you want to log whenever an exception occurs - if you only want to log the ones you actually catch, then don't put the "Perform action" in a finally block, just put it after the end of the inner try-catch.