Dart Programming - Exceptions



An exception (or exceptional event) is a problem that arises during the execution of a program. When an Exception occurs the normal flow of the program is disrupted and the program/Application terminates abnormally.

Built-in Dart exceptions include −

Sr.No Exceptions & Description
1

DeferredLoadException

Thrown when a deferred library fails to load.

2

FormatException

Exception thrown when a string or some other data does not have an expected format and cannot be parsed or processed.

3

IntegerDivisionByZeroException

Thrown when a number is divided by zero.

4

IOException

Base class for all Inupt-Output related exceptions.

5

IsolateSpawnException

Thrown when an isolate cannot be created.

6

Timeout

Thrown when a scheduled timeout happens while waiting for an async result.

Every exception in Dart is a subtype of the pre-defined class Exception. Exceptions must be handled to prevent the application from terminating abruptly.

The try / on / catch Blocks

The try block embeds code that might possibly result in an exception. The on block is used when the exception type needs to be specified. The catch block is used when the handler needs the exception object.

The try block must be followed by either exactly one on / catch block or one finally block (or one of both). When an exception occurs in the try block, the control is transferred to the catch.

The syntax for handling an exception is as given below −

try { 
   // code that might throw an exception 
}  
on Exception1 { 
   // code for handling exception 
}  
catch Exception2 { 
   // code for handling exception 
} 

Following are some points to remember −

  • A code snippet can have more than one on / catch blocks to handle multiple exceptions.

  • The on block and the catch block are mutually inclusive, i.e. a try block can be associated with both- the on block and the catch block.

The following code illustrates exception handling in Dart −

Example: Using the ON Block

The following program divides two numbers represented by the variables x and y respectively. The code throws an exception since it attempts division by zero. The on block contains the code to handle this exception.

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try {
      res = x ~/ y; 
   } 
   on IntegerDivisionByZeroException { 
      print('Cannot divide by zero'); 
   } 
} 

It should produce the following output

Cannot divide by zero

Example: Using the catch Block

In the following example, we have used the same code as above. The only difference is that the catch block (instead of the ON block) here contains the code to handle the exception. The parameter of catch contains the exception object thrown at runtime.

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try {  
      res = x ~/ y; 
   }  
   catch(e) { 
      print(e); 
   } 
} 

It should produce the following output

IntegerDivisionByZeroException

Example: on…catch

The following example shows how to use the on...catch block.

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try { 
      res = x ~/ y; 
   }  
   on IntegerDivisionByZeroException catch(e) { 
      print(e); 
   } 
} 

It should produce the following output

IntegerDivisionByZeroException

The Finally Block

The finally block includes code that should be executed irrespective of an exception’s occurrence. The optional finally block executes unconditionally after try/on/catch.

The syntax for using the finally block is as follows −

try { 
   // code that might throw an exception 
}  
on Exception1 { 
   // exception handling code 
}  
catch Exception2 { 
   //  exception handling 
}  
finally { 
   // code that should always execute; irrespective of the exception 
}

The following example illustrates the use of finally block.

main() { 
   int x = 12; 
   int y = 0; 
   int res;  
   
   try { 
      res = x ~/ y; 
   } 
   on IntegerDivisionByZeroException { 
      print('Cannot divide by zero'); 
   } 
   finally { 
      print('Finally block executed'); 
   } 
}

It should produce the following output

Cannot divide by zero 
Finally block executed

Throwing an Exception

The throw keyword is used to explicitly raise an exception. A raised exception should be handled to prevent the program from exiting abruptly.

The syntax for raising an exception explicitly is −

throw new Exception_name()

Example

The following example shows how to use the throw keyword to throw an exception −

main() { 
   try { 
      test_age(-2); 
   } 
   catch(e) { 
      print('Age cannot be negative'); 
   } 
}  
void test_age(int age) { 
   if(age<0) { 
      throw new FormatException(); 
   } 
}

It should produce the following output

Age cannot be negative

Custom Exceptions

As specified above, every exception type in Dart is a subtype of the built-in class Exception. Dart enables creating custom exceptions by extending the existing ones. The syntax for defining a custom exception is as given below −

Syntax: Defining the Exception

class Custom_exception_Name implements Exception { 
   // can contain constructors, variables and methods 
} 

Custom Exceptions should be raised explicitly and the same should be handled in the code.

Example

The following example shows how to define and handle a custom exception.

class AmtException implements Exception { 
   String errMsg() => 'Amount should be greater than zero'; 
}  
void main() { 
   try { 
      withdraw_amt(-1); 
   } 
   catch(e) { 
      print(e.errMsg()); 
   }  
   finally { 
      print('Ending requested operation.....'); 
   } 
}  
void withdraw_amt(int amt) { 
   if (amt <= 0) { 
      throw new AmtException(); 
   } 
}  

In the above code, we are defining a custom exception, AmtException. The code raises the exception if the amount passed is not within the excepted range. The main function encloses the function invocation in the try...catch block.

The code should produce the following output

Amount should be greater than zero 
Ending requested operation.... 
Advertisements