Error Handling Techniques
Error Handling Techniques Interview with follow-up questions
1. What are some of the common error handling techniques in Flutter?
A complete answer covers both language-level mechanics and app-level hooks — interviewers want to hear the global ones, not just try/catch.
Language level (Dart):
try/on/catch/finally— catch specific or general exceptions for sync andawaited code;finallyfor guaranteed cleanup.throwto raise an exception, andrethrowto re-raise a caught one while preserving its original stack trace.Future.catchError/.then(onError:)andStream'sonErrorfor callback-style async.
App / framework level (Flutter):
FlutterError.onError— central hook for errors thrown during build/layout/paint inside the framework.PlatformDispatcher.instance.onError— catches uncaught async errors app-wide; this largely replaced wrappingmaininrunZonedGuarded.ErrorWidget.builder— replace the red/grey error screen with a friendly fallback widget.- Crash reporting — funnel the above into Sentry or Firebase Crashlytics for production stack traces.
void main() {
FlutterError.onError = (details) {
FlutterError.presentError(details);
Crashlytics.instance.recordFlutterError(details);
};
PlatformDispatcher.instance.onError = (error, stack) {
Crashlytics.instance.recordError(error, stack);
return true; // handled
};
runApp(const MyApp());
}
Gotcha: logging an error isn't recovery — pair these hooks with UI fallbacks (retry buttons, cached data, an error state) so the user isn't stuck. And catch specific exception types; swallowing everything (including Errors) hides real bugs.
Follow-up 1
Can you explain how try-catch works in Flutter?
In Flutter, try-catch blocks are used to catch and handle exceptions. The code inside the try block is executed, and if an exception is thrown, it is caught by the catch block. The catch block can handle the exception by executing specific code or rethrowing the exception. Here's an example:
try {
// Code that may throw an exception
} catch (e) {
// Code to handle the exception
}
Follow-up 2
What is the role of 'finally' block in error handling?
The 'finally' block in error handling is used to execute code regardless of whether an exception is thrown or not. It is executed after the try and catch blocks, regardless of whether an exception was caught or not. This can be useful for cleaning up resources or ensuring that certain code is always executed. Here's an example:
try {
// Code that may throw an exception
} catch (e) {
// Code to handle the exception
} finally {
// Code to be executed regardless of whether an exception was caught
}
Follow-up 3
How does the 'on' clause work in error handling?
The 'on' clause in error handling is used to catch specific types of exceptions. It allows you to specify the type of exception you want to catch, and the catch block will only be executed if that specific type of exception is thrown. Here's an example:
try {
// Code that may throw an exception
} on ExceptionType {
// Code to handle the specific type of exception
}
Follow-up 4
Can you explain the concept of 'throw' and 'rethrow' in Flutter?
In Flutter, the 'throw' keyword is used to manually throw an exception. It allows you to create and throw custom exceptions or throw built-in exceptions. The 'rethrow' keyword is used to rethrow an exception that was caught. It is typically used inside a catch block to propagate the exception to the next level of error handling. Here's an example:
try {
// Code that may throw an exception
} catch (e) {
// Code to handle the exception
rethrow;
}
Follow-up 5
What is the difference between 'throw' and 'rethrow'?
The 'throw' keyword is used to manually throw an exception, while the 'rethrow' keyword is used to rethrow an exception that was caught. The main difference is that 'throw' is used to initiate the throwing of an exception, while 'rethrow' is used to propagate an exception that was already caught. 'throw' can be used anywhere in the code, while 'rethrow' is typically used inside a catch block. Here's an example:
try {
// Code that may throw an exception
} catch (e) {
// Code to handle the exception
rethrow;
}
2. How can you handle asynchronous errors in Flutter?
It depends on whether you're using async/await or raw Future/Stream callbacks — name both.
With async/await (preferred): just use try/catch. Awaiting a failing Future throws into the surrounding block, so the same construct that handles sync errors handles async ones:
Future loadUser() async {
try {
final res = await api.get('/me'); // throws here on failure
return User.fromJson(res.data);
} on TimeoutException {
rethrow;
} catch (e, st) {
reportError(e, st);
rethrow;
}
}
With raw futures/streams: use catchError / onError:
api.get('/me').then(handle).catchError((e) => showError(e));
stream.listen(onData, onError: (e, st) => log(e), cancelOnError: false);
Uncaught async errors — anything thrown in a Future you didn't await or handle — won't be caught locally. In 2026 the idiom is the global hook PlatformDispatcher.instance.onError, which replaced most runZonedGuarded boilerplate:
PlatformDispatcher.instance.onError = (error, stack) {
Crashlytics.instance.recordError(error, stack);
return true; // mark handled
};
Gotchas:
- A surrounding
try/catchdoes not catch errors from an un-awaitedFuture— eitherawaitit or attach.catchError. - For streams, decide
cancelOnError— by default an error terminates the subscription. - Don't mix
awaitwith.catchErroron the same call; pick one style.
Follow-up 1
What is the role of 'catchError' in handling asynchronous errors?
The 'catchError' method is used to handle errors that occur during asynchronous operations in Flutter. It allows you to specify a callback function that will be called when an error occurs. This callback function can then handle the error in any way you want, such as displaying an error message to the user or logging the error for debugging purposes.
Follow-up 2
Can you explain how 'Future.error' works in Flutter?
In Flutter, the 'Future.error' method is used to create a 'Future' object that represents an error. This method takes an error object as a parameter and returns a 'Future' object that immediately completes with the specified error. You can then use this 'Future' object to handle the error using the 'catchError' method or other error handling mechanisms.
Follow-up 3
How can you handle errors in 'Stream'?
In Flutter, you can handle errors in 'Stream' by using the 'onError' method. This method allows you to specify a callback function that will be called when an error occurs in the stream. The callback function will receive the error object as a parameter and can handle the error in any way you want, such as displaying an error message or logging the error.
Follow-up 4
What is the difference between 'catchError' and 'try-catch' in handling asynchronous errors?
The main difference between 'catchError' and 'try-catch' in handling asynchronous errors is that 'catchError' is used for handling errors that occur during asynchronous operations, while 'try-catch' is used for handling errors that occur during synchronous operations. 'catchError' is specifically designed for handling errors in asynchronous code and provides a convenient way to handle errors without blocking the execution of other asynchronous operations.
Follow-up 5
Can you give an example of handling asynchronous errors in Flutter?
Sure! Here's an example of handling asynchronous errors in Flutter using the 'catchError' method:
void fetchData() {
http.get('https://api.example.com/data')
.then((response) {
// Process the response
})
.catchError((error) {
// Handle the error
print('An error occurred: $error');
});
}
3. How can you handle exceptions at the widget level in Flutter?
"Widget-level" error handling means two distinct things, and a good answer separates them: global hooks that catch errors thrown while a widget builds, and local recovery so one broken widget doesn't take down the screen. Note RaisedButton was removed — use ElevatedButton.
Global build-error hooks — ErrorWidget.builder replaces the error screen; FlutterError.onError reports it:
void main() {
ErrorWidget.builder = (FlutterErrorDetails details) =>
const Center(child: Text('Oops! Something went wrong.'));
FlutterError.onError = (details) {
FlutterError.presentError(details);
Crashlytics.instance.recordFlutterError(details); // report in release
};
runApp(const MyApp());
}
Local recovery — wrap a risky subtree so only it fails:
Widget _safe(Widget Function() build) {
try {
return build();
} catch (e, st) {
FlutterError.reportError(FlutterErrorDetails(exception: e, stack: st));
return const _FallbackTile();
}
}
Points interviewers want:
ErrorWidget.builderis mostly cosmetic — in release the default is a grey box, so set a friendly fallback and report viaFlutterError.onError, or users see a blank screen with no telemetry.- A
try/catchinsidebuild()only catches synchronous build errors. Async errors (e.g. in aFutureBuilder's future) surface through the builder'ssnapshot.hasError— handle that explicitly.
Gotcha: ErrorWidget.builder can itself throw (e.g. if it depends on an InheritedWidget not present at error time) — keep the fallback widget dead simple and self-contained.
Follow-up 1
What is the role of 'FlutterError.onError' in widget level error handling?
The FlutterError.onError method is used to handle errors that occur at the widget level in Flutter. It allows you to define a callback function that will be called whenever an error occurs. This callback function can be used to perform any necessary actions, such as logging the error or displaying a custom error message.
Here is an example of how you can use FlutterError.onError to handle errors:
void main() {
FlutterError.onError = (FlutterErrorDetails errorDetails) {
// Perform error handling actions
print('Error occurred: ${errorDetails.exception}');
};
runApp(MyApp());
}
Follow-up 2
Can you explain how 'ErrorWidget.builder' works?
The ErrorWidget.builder method is used to customize the error display at the widget level in Flutter. It allows you to define a callback function that will be called whenever an error occurs. This callback function should return a widget that will be displayed instead of the default error message.
Here is an example of how you can use ErrorWidget.builder to customize the error display:
void main() {
ErrorWidget.builder = (FlutterErrorDetails errorDetails) {
return MyCustomErrorWidget();
};
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Error Handling',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Widget Level Error Handling'),
),
body: Center(
child: RaisedButton(
onPressed: () {
throw Exception('This is an example exception');
},
child: Text('Throw Exception'),
),
),
);
}
}
class MyCustomErrorWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('Oops! Something went wrong.'),
);
}
}
Follow-up 3
What is the purpose of 'FlutterErrorDetails'?
The FlutterErrorDetails class is used to provide detailed information about an error that occurs in Flutter. It contains properties such as the exception, stack trace, and the context in which the error occurred. This information can be useful for debugging and error handling purposes.
Here is an example of how you can use FlutterErrorDetails to handle errors:
void main() {
FlutterError.onError = (FlutterErrorDetails errorDetails) {
// Perform error handling actions
print('Error occurred: ${errorDetails.exception}');
print('Stack trace: ${errorDetails.stack}');
print('Context: ${errorDetails.context}');
};
runApp(MyApp());
}
Follow-up 4
How can you customize the error display at the widget level?
To customize the error display at the widget level in Flutter, you can use the ErrorWidget.builder method. This method allows you to define a callback function that will be called whenever an error occurs. This callback function should return a widget that will be displayed instead of the default error message.
Here is an example of how you can customize the error display:
void main() {
ErrorWidget.builder = (FlutterErrorDetails errorDetails) {
return MyCustomErrorWidget();
};
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Error Handling',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Widget Level Error Handling'),
),
body: Center(
child: RaisedButton(
onPressed: () {
throw Exception('This is an example exception');
},
child: Text('Throw Exception'),
),
),
);
}
}
class MyCustomErrorWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('Oops! Something went wrong.'),
);
}
}
Follow-up 5
Can you give an example of widget level error handling in Flutter?
Sure! Here is an example of how you can handle errors at the widget level in Flutter:
void main() {
ErrorWidget.builder = (FlutterErrorDetails errorDetails) {
return MyCustomErrorWidget();
};
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Error Handling',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Widget Level Error Handling'),
),
body: Center(
child: RaisedButton(
onPressed: () {
throw Exception('This is an example exception');
},
child: Text('Throw Exception'),
),
),
);
}
}
class MyCustomErrorWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('Oops! Something went wrong.'),
);
}
}
4. How can you handle platform-specific errors in Flutter?
Platform-specific errors come from the native side of a platform channel (a plugin or your own MethodChannel). When native code fails, Flutter surfaces it as a PlatformException, which you catch around the awaited invocation.
try {
final result = await _channel.invokeMethod('getBatteryLevel');
return result as int;
} on PlatformException catch (e) {
// e.code -> a string error code from the native side
// e.message -> human-readable message
// e.details -> optional structured payload
switch (e.code) {
case 'UNAVAILABLE':
return null; // feature not supported on this device
default:
reportError(e);
rethrow;
}
} on MissingPluginException {
// method not implemented on this platform (or plugin not registered)
return null;
}
What interviewers want:
PlatformExceptioncarriescode,message, anddetails— branch oncodeto react to specific native failures rather than treating all platform errors the same.MissingPluginExceptionis distinct and common: it means the platform side has no implementation for that method (often web/desktop, or a plugin not registered) — handle it so the feature degrades gracefully instead of crashing.- For per-platform branching, check
Platform.isIOS/isAndroid(guard withkIsWebfirst, sincedart:io'sPlatformisn't available on web).
Gotcha: native exceptions don't auto-propagate as Dart exceptions unless the channel call is awaited inside a try/catch — fire-and-forget invokeMethod calls swallow the error. Always await and catch.
Follow-up 1
What is the role of 'PlatformException' in Flutter?
The PlatformException class in Flutter is used to represent errors that occur on the platform side. It is a subclass of the Exception class and provides additional properties like code and message to provide more information about the error.
When a platform-specific method call fails, it throws a PlatformException with the relevant error information. You can catch this exception and handle the error in your Flutter code.
Follow-up 2
How can you handle 'MissingPluginException'?
The MissingPluginException is a specific type of PlatformException that is thrown when a platform-specific plugin is not found. This can happen if the plugin is not installed or if there is a version mismatch between the plugin and the Flutter framework.
To handle a MissingPluginException, you can catch it using a try-catch block and take appropriate action. For example, you can display an error message to the user or provide a fallback functionality.
Follow-up 3
Can you explain how 'AndroidException' and 'IOSException' work?
The AndroidException and IOSException classes are subclasses of the PlatformException class and are used to represent platform-specific errors on Android and iOS respectively.
When a platform-specific method call fails on Android, it throws an AndroidException with the relevant error information. Similarly, on iOS, it throws an IOSException.
You can catch these exceptions using a try-catch block and handle the errors specific to each platform. The code property of these exceptions can be used to determine the specific error that occurred.
Follow-up 4
How can you handle errors in platform channels?
To handle errors in platform channels, you can use the MethodChannel or EventChannel classes provided by the Flutter framework.
When making method calls or listening to events through platform channels, you can use the invokeMethod or setMethodCallHandler methods respectively, which return a Future that can be used to handle any errors that occur.
You can chain a catchError callback to the Future returned by these methods to catch any errors and take appropriate action. The error can be an instance of PlatformException or any other exception that occurred during the method call or event handling.
Follow-up 5
Can you give an example of handling platform-specific errors in Flutter?
Sure! Here's an example of handling a platform-specific error in Flutter using the PlatformException class:
try {
// Call a platform-specific method
await platform.invokeMethod('someMethod');
} catch (e) {
if (e is PlatformException) {
// Handle the specific error
if (e.code == 'someErrorCode') {
// Take appropriate action
} else if (e.code == 'anotherErrorCode') {
// Take another action
}
}
}
In this example, we are calling a platform-specific method using the invokeMethod method of a MethodChannel. If an error occurs, it is caught in the catch block. We then check if the error is an instance of PlatformException and handle the specific error based on its code property.
5. How can you handle errors in Flutter plugins?
Plugin errors are really platform-channel errors, so you handle them where you call the plugin, catching the channel's typed exceptions. The three channel types (MethodChannel, EventChannel, BasicMessageChannel) each have a slightly different failure surface.
MethodChannel (request/response): native failures arrive as PlatformException; an unimplemented method arrives as MissingPluginException.
try {
await SomePlugin.doNativeThing();
} on PlatformException catch (e) {
handle(e.code, e.message); // structured native error
} on MissingPluginException {
// plugin not available on this platform / not registered
}
EventChannel (streams): errors come through the stream's onError, not a try/catch:
sensorEvents.listen(
onData,
onError: (e) => log('sensor error: $e'),
cancelOnError: false,
);
BasicMessageChannel (free-form messages): wrap send() in try/catch like any async call.
What interviewers want you to add:
- Web/desktop gaps — many plugins are mobile-only, so
MissingPluginExceptionis a real path; checkkIsWeb/Platformand provide a fallback. - Permissions — plugin calls often fail because a runtime permission was denied; surface that as a user-actionable message, not a crash.
- Report, don't swallow — pipe unexpected plugin errors into Sentry/Crashlytics via
FlutterError.onError/PlatformDispatcher.onError.
Gotcha: a plugin author defines the code strings in PlatformException — check the plugin's docs for which codes it throws rather than guessing, and always handle MissingPluginException separately.
Follow-up 1
What is the role of 'PluginUtilities' in error handling?
'PluginUtilities' is a utility class provided by the Flutter framework that helps with error handling in plugins. It provides methods like 'getCallbackHandle' and 'getCallbackFromHandle' which can be used to obtain a callback handle and convert it back to a callback function respectively. These methods are useful when handling errors related to callback functions in plugins.
Follow-up 2
How can you handle 'MissingPluginException' in plugins?
The 'MissingPluginException' is thrown when a platform-specific implementation is not available for a plugin method call. To handle this exception, you can use a try-catch block and catch the 'MissingPluginException' specifically. You can then handle the exception by providing a fallback behavior or displaying an error message to the user.
Follow-up 3
Can you explain how 'MethodChannel' works in error handling?
The 'MethodChannel' class in Flutter is used for platform-specific method calls. When an error occurs during a method call, the platform-specific implementation can throw an exception. To handle this exception, you can use a try-catch block and catch the specific exception type thrown by the platform implementation. You can then handle the exception by providing appropriate error handling logic.
Follow-up 4
How can you handle errors in 'EventChannel' and 'BasicMessageChannel'?
To handle errors in 'EventChannel' and 'BasicMessageChannel', you can use the 'Stream.error' property for 'EventChannel' and the 'BasicMessageChannel.setMessageHandler' method for 'BasicMessageChannel'. These error handling mechanisms allow you to handle errors that occur during event stream subscription or message handling respectively.
Follow-up 5
Can you give an example of handling errors in Flutter plugins?
Sure! Here's an example of handling errors in a Flutter plugin using the 'MethodChannel':
try {
final result = await platform.invokeMethod('methodName');
// Handle successful result
} catch (e) {
if (e is PlatformException) {
// Handle specific platform exception
} else {
// Handle generic exception
}
}
Live mock interview
Mock interview: Error Handling Techniques
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.