All exceptions in Dart are unchecked exceptions. You don’t need to declare thrown types on functions, and catching errors is not mandatory.
There are two core categories:
Exception: Predictable business errors (invalid format, bad parameters, etc. Recommended to catch and handle).Error: Fatal program failures (type mismatches, null pointer access, unimplemented methods, etc. Generally not caught).
Any non-null object can be thrown via throw. Standard projects should only throw subclasses of Exception/Error.
Uncaught exceptions terminate the current isolate and crash the entire application.
throw – Throwing Exceptions
1. Throw built-in system exceptions
void main() {
// Format error
throw FormatException("At least one data segment is required");
}
Code language: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
FormatException: Error description
#0 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:3:3)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
This snippet manually triggers a built-in exception with a custom message. You might wonder what purpose this serves, but throwing errors is critical for real-world logic. Take user registration as an example: we validate input formats. If input breaks the rules, we throw an error immediately to notify users and block malformed data from polluting our data layer.
2. Throwing arbitrary objects
Not recommended for production builds
void main() {
throw "Custom error message text!";
}Code language: Dart (dart)
Execution output
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
Custom error message text!
#0 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:2:3)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
3. throw inside arrow functions (throw counts as an expression)
class Point {}
void distanceTo(Point other) => throw UnimplementedError("This method has not been implemented");
void main() {
distanceTo(Point());
}
Code language: JavaScript (javascript)
try / on / catch – Catching Exceptions
Syntax Differences
on ExceptionType: Matches only the specified exception type; cannot access the exception instance.catch(e): Catches all exceptions; variable e holds the exception instance.catch(e, s): e = exception object, s = StackTrace call stack data.
1: Catch single specific exception with on
// Create custom exception implementing standard Exception
class OutOfLlamasException implements Exception {}
// Function that throws our custom error
void breedMoreLlamas() {
throw OutOfLlamasException();
}
void buyMoreLlamas() {
print("buyMoreLlamas function executed");
}
void main() {
try {
breedMoreLlamas(); // Execute risky logic
} on OutOfLlamasException {
buyMoreLlamas(); // Runs if OutOfLlamasException is caught
}
}Code language: Dart (dart)
Execution output
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
buyMoreLlamas function executedCode language: JavaScript (javascript)
try {
// Code that may crash
} on ExceptionType {
// Logic to run after catching the error
}Code language: Dart (dart)
try on is a dedicated syntax for type-specific exception capture.
2: Multi-layer sequential exception capture
More specific match branches run first
class OutOfLlamasException implements Exception {}
void breedMoreLlamas() {
throw FormatException("Data format mismatch");
}
void main() {
try {
breedMoreLlamas();
}
// 1. Exact match for custom exception
on OutOfLlamasException {
print("Caught OutOfLlamasException error");
}
// 2. Catch all subclasses of Exception
on Exception catch (e) {
print("General business exception: $e");
}
// 3. Fallback catch for Errors and any other thrown objects
catch (e) {
print("Unknown critical error: $e");
}
}
Code language: Dart (dart)
Output: General business exception: FormatException: Data format mismatch
We can use multiple on blocks to target distinct exception types, plus a final catch as universal fallback.
3: Capture exception and print full StackTrace
void main() {
try {
int a = null;
print(a + 1);
} catch (e, stack) {
print("Exception message: $e");
print("Full call stack trace:\n$stack");
}
}
Code language: Dart (dart)
This code prints both the error message and the complete function call stack for debugging.
D:\dartdemo\firstdart>dart run
Building package executable...
Failed to build firstdart:firstdart:
bin/firstdart.dart:3:13: Error: A value of type 'Null' can't be assigned to a variable of type 'int'.
int a = null;Code language: PHP (php)
rethrow
Handle partial logic then bubble the error upward
Purpose: Process part of the error logic inside the current function, then pass the exception to upstream caller code for further handling.
Sometimes we need to run recovery logic locally while also letting the parent caller receive the error for additional processing.
void misbehave() {
try {
dynamic foo = true;
print(foo++); // true cannot be incremented, triggers runtime error
} catch (e) {
print("Local handling inside misbehave: ${e.runtimeType}");
rethrow; // Re-throw to outer try block
}
}
void main() {
try {
misbehave();
} catch (e) {
print("Final handling inside main: ${e.runtimeType}");
}
}
Code language: Dart (dart)
Execution flow:
Local handling inside misbehave: NoSuchMethodError
Final handling inside main: NoSuchMethodError
Code language: PHP (php)
The error gets processed both inside misbehave and the main entry point.
finally Block
Guaranteed to execute regardless of errors
Two common usage patterns:
- try + finally only: Errors are not caught; program crashes after running finally logic.
- try + catch + finally: Process error first, then run finally (standard for resource cleanup).
1: try + finally
void cleanLlamaStalls() => print("Clean up resources, guaranteed execution");
void breedMoreLlamas() => throw Exception("Runtime error occurred");
void main() {
try {
breedMoreLlamas();
} finally {
cleanLlamaStalls();
}
}
Code language: Dart (dart)
The cleanup code runs, but the uncaught error still crashes the program afterward.
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Clean up resources, guaranteed execution
Unhandled exception:
Exception: Runtime error occurred
#0 breedMoreLlamas (file:///D:/dartdemo/firstdart/bin/firstdart.dart:2:27)
#1 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:5)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#3 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
2: try + catch + finally
Standard template for resource release, e.g. closing file streams
void cleanLlamaStalls() => print("Close files / release occupied resources");
void breedMoreLlamas() => throw FormatException("Parsing failed");
void main() {
try {
breedMoreLlamas();
} catch (e) {
print("Caught exception: $e");
} finally {
cleanLlamaStalls();
}
}
Code language: Dart (dart)
Execution order: Error triggered → catch block runs → finally block executes last
Execution output
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Caught exception: FormatException: Parsing failed
Close files / release occupied resources
Code language: PHP (php)
assert Assertions
Only active during development & debugging; fully disabled in production builds
assert(booleanCondition, [optionalErrorText])
Throws AssertionError when condition evaluates to false; completely ignored in release builds with zero performance overhead.
1: Basic assertion example
void main() {
String? text;
int number = 120;
String url = "http://foxdevelop.com";
assert(text != null); // Nullability check
assert(number < 100); // Numeric range validation
assert(url.startsWith("https")); // URL protocol check
}
Code language: JavaScript (javascript)
Running this code produces no visible output by default!
Assertions are turned off globally unless you explicitly enable them via launch flags, read below for details.
2: Custom human-readable error message
void main() {
String url = "http://test.com";
assert(
url.startsWith("https"),
"URL $url must start with https protocol",
);
}
Code language: JavaScript (javascript)
We can define custom descriptive text to show when an assertion fails.
How to Enable Assertions
- Flutter Debug mode enables assertions by default
- Direct dart command:
dart --enable-asserts your-file-name.dart - Production compilation: All assertions are stripped entirely with no runtime cost
D:\dartdemo\firstdart\bin>dart --enable-asserts firstdart.dart
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
dart run behaves the same as raw dart command; assertions stay disabled unless you add the --enable-asserts flag:
Run command example:
dart run --enable-asserts main.dartCode language: CSS (css)
If your terminal working directory is the project root, run this shorthand:
Run command:
dart run --enable-asserts
dart run: Directly execute Dart source files for local development testing
dart filename: Simplified single-file run syntax
dart compile exe: Build standalone binary executables; assertions are permanently disabled in compiled output
The Dart source file lives inside the bin subfolder, so you can either cd into bin to run the file directly, or execute the command from the project root folder one level above bin.
dart run –enable-asserts
Below shows both execution methods: running inside bin folder, and running from project root parent directory.
D:\dartdemo\firstdart\bin>dart --enable-asserts firstdart.dart
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)
D:\dartdemo\firstdart\bin>dart run
Building package executable...
Built firstdart:firstdart.
D:\dartdemo\firstdart\bin>cd ..
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
'file:///D:/dartdemo/firstdart/bin/firstdart.dart': Failed assertion: line 6 pos 10: 'text != null': is not true.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2 main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:6:10)
#3 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#4 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)
No error will be thrown if the assertion condition evaluates to true
Modify the example code: change http to https on url, switch text != null to text == null, set number value to 99
void main() {
String? text;
int number = 99;
String url = "https://foxdevelop.com";
assert(text == null); // Nullability check
assert(number < 100); // Numeric range validation
assert(url.startsWith("https")); // URL protocol check
}Code language: Dart (dart)
Running this updated version outputs zero errors
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.Code language: CSS (css)
Full Combined Demo
void cleanResource() => print("finally block: Release occupied resources");
void testError() {
try {
int num = 150;
assert(num < 100, "Number value must be less than 100");
throw FormatException("Invalid data format");
} on FormatException catch (e) {
print("Caught format exception: $e");
rethrow;
} finally {
cleanResource();
}
}
void main() {
try {
testError();
} catch (e) {
print("main catches re-thrown exception: $e");
}
}
Code language: PHP (php)
Execution output
D:\dartdemo\firstdart>dart run --enable-asserts
Building package executable...
Built firstdart:firstdart.
finally block: Release occupied resources
main catches re-thrown exception: 'file:///D:/dartdemo/firstdart/bin/firstdart.dart':
Failed assertion: line 6 pos 12: 'num < 100': Number value must be less than 100Code language: PHP (php)