CINXE.COM

Futures and error handling | Dart

<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="x-ua-compatible" content="ie=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><script>!function(e,t,a,n){e[n]=e[n]||[],e[n].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var g=t.getElementsByTagName(a)[0],m=t.createElement(a);m.async=!0,m.src="https://www.googletagmanager.com/gtm.js?id=GTM-5VSZM5J",g.parentNode.insertBefore(m,g)}(window,document,"script","dataLayer")</script><meta name="description" content="Everything you wanted to know about handling errors and exceptions when writing asynchronous code. And then some."><title>Futures and error handling | Dart</title><link rel="icon" sizes="64x64" href="/assets/img/logo/dart-64.png" eleventy:ignore><link href="/assets/img/touch-icon-iphone.png" rel="apple-touch-icon" eleventy:ignore><link href="/assets/img/touch-icon-ipad.png" rel="apple-touch-icon" sizes="152x152" eleventy:ignore><link href="/assets/img/touch-icon-iphone-retina.png" rel="apple-touch-icon" sizes="180x180" eleventy:ignore><link href="/assets/img/touch-icon-ipad-retina.png" rel="apple-touch-icon" sizes="167x167" eleventy:ignore><meta name="twitter:card" content="summary"><meta name="twitter:site" content="@dart_lang"><meta name="twitter:title" content="Futures and error handling"><meta name="twitter:description" content="Everything you wanted to know about handling errors and exceptions when writing asynchronous code. And then some."><meta property="og:title" content="Futures and error handling"><meta property="og:description" content="Everything you wanted to know about handling errors and exceptions when writing asynchronous code. And then some."><meta property="og:url" content="/libraries/async/futures-error-handling/"><meta property="og:image" content="/assets/img/logo/dart-logo-for-shares.png?2" eleventy:ignore><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Display:wght@400&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Text:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" rel="stylesheet"><link rel="stylesheet" href="/assets/css/main.css"><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.min.js" integrity="sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/3.0.5/js.cookie.min.js" integrity="sha512-nlp9/l96/EpjYBx7EP7pGASVXNe80hGhYAUrjeXnu/fyF5Py0/RXav4BBNs7n5Hx1WFhOEOWSAVjGeC3oKxDVQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="/assets/js/os-tabs.js"></script><script src="/assets/js/utilities.js"></script><script src="/assets/js/main.js"></script><script>!function(e,a,t,n,c,o,s){e.GoogleAnalyticsObject=c,e[c]=e[c]||function(){(e[c].q=e[c].q||[]).push(arguments)},e[c].l=1*new Date,o=a.createElement(t),s=a.getElementsByTagName(t)[0],o.async=1,o.src="//www.google-analytics.com/analytics.js",s.parentNode.insertBefore(o,s)}(window,document,"script",0,"ga"),ga("create","UA-26406144-4","auto"),ga("send","pageview")</script></head><body class="default.html show_banner"><a id="skip" href="#site-content-title">Skip to main content</a><section id="cookie-notice"><div class="container"><p>dart.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic. <a href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a>.</p><button id="cookie-consent" class="btn btn-primary">OK, got it</button></div></section><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5VSZM5J" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><header id="page-header" class="site-header"><nav id="mainnav" class="site-header"><div id="menu-toggle"><i class="material-symbols">menu</i></div><a href="/" class="brand" title="Dart"><img src="/assets/img/logo/logo-white-text.svg" alt="Dart"></a><ul class="navbar"><li><a href="/overview" class="nav-link">Overview</a></li><li class="mainnav__get-started"><a href="/guides" class="nav-link active"><span>Docs</span></a></li><li><a href="/community" class="nav-link">Community</a></li><li><a href="/#try-dart" class="nav-link">Try Dart</a></li><li><a href="/get-dart" class="nav-link">Get Dart</a></li><li class="searchfield"><form action="/search" class="site-header__search form-inline" id="cse-search-box"><input type="hidden" name="cx" value="011220921317074318178:_yy-tmb5t_i"> <input type="hidden" name="ie" value="UTF-8"> <input type="hidden" name="hl" value="en"> <input class="site-header__searchfield form-control search-field" type="search" name="q" id="search-main" autocomplete="off" placeholder="Search" aria-label="Search"></form></li></ul></nav></header><div class="banner"><p class="banner__text">Announcing Dart 3.5 and an updated Dart roadmap! <a href="https://medium.com/dartlang/dart-3-5-6ca36259fa2f" target="_blank">Learn more</a></p></div><div id="sidenav"><form action="/search/" class="site-header__search form-inline"><input class="site-header__searchfield form-control search-field" type="search" name="q" id="search-side" autocomplete="off" placeholder="Search" aria-label="Search"></form><div class="site-sidebar"><ul class="navbar-nav"><li class="nav-item"><a href="/overview" class="nav-link">Overview</a></li><li class="nav-item"><a href="/community" class="nav-link">Community</a></li><li class="nav-item"><a href="https://dartpad.dev" class="nav-link">Try Dart</a></li><li class="nav-item"><a href="/get-dart" class="nav-link">Get Dart</a></li><li class="nav-item"><a href="/guides" class="nav-link">Docs</a></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li></ul><ul class="nav flex-column"><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-1" role="button" aria-expanded="false" aria-controls="sidenav-1">Language</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1"><li class="nav-item"><a class="nav-link" href="/language">Introduction</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-2" href="#sidenav-1-2" role="button" aria-expanded="false" aria-controls="sidenav-1-2">Syntax basics</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-2"><li class="nav-item"><a class="nav-link" href="/language/variables">Variables</a></li><li class="nav-item"><a class="nav-link" href="/language/operators">Operators</a></li><li class="nav-item"><a class="nav-link" href="/language/comments">Comments</a></li><li class="nav-item"><a class="nav-link" href="/language/metadata">Metadata</a></li><li class="nav-item"><a class="nav-link" href="/language/libraries">Libraries & imports</a></li><li class="nav-item"><a class="nav-link" href="/language/keywords">Keywords</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-3" href="#sidenav-1-3" role="button" aria-expanded="false" aria-controls="sidenav-1-3">Types</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-3"><li class="nav-item"><a class="nav-link" href="/language/built-in-types">Built-in types</a></li><li class="nav-item"><a class="nav-link" href="/language/records">Records</a></li><li class="nav-item"><a class="nav-link" href="/language/collections">Collections</a></li><li class="nav-item"><a class="nav-link" href="/language/generics">Generics</a></li><li class="nav-item"><a class="nav-link" href="/language/typedefs">Typedefs</a></li><li class="nav-item"><a class="nav-link" href="/language/type-system">Type system</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-4" href="#sidenav-1-4" role="button" aria-expanded="false" aria-controls="sidenav-1-4">Patterns</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-4"><li class="nav-item"><a class="nav-link" href="/language/patterns">Overview & usage</a></li><li class="nav-item"><a class="nav-link" href="/language/pattern-types">Pattern types</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/dart-patterns-records" target="_blank" rel="noopener">Applied tutorial</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/language/functions">Functions</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-6" href="#sidenav-1-6" role="button" aria-expanded="false" aria-controls="sidenav-1-6">Control flow</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-6"><li class="nav-item"><a class="nav-link" href="/language/loops">Loops</a></li><li class="nav-item"><a class="nav-link" href="/language/branches">Branches</a></li><li class="nav-item"><a class="nav-link" href="/language/error-handling">Error handling</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-7" href="#sidenav-1-7" role="button" aria-expanded="false" aria-controls="sidenav-1-7">Classes & objects</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-7"><li class="nav-item"><a class="nav-link" href="/language/classes">Classes</a></li><li class="nav-item"><a class="nav-link" href="/language/constructors">Constructors</a></li><li class="nav-item"><a class="nav-link" href="/language/methods">Methods</a></li><li class="nav-item"><a class="nav-link" href="/language/extend">Extend a class</a></li><li class="nav-item"><a class="nav-link" href="/language/mixins">Mixins</a></li><li class="nav-item"><a class="nav-link" href="/language/enums">Enums</a></li><li class="nav-item"><a class="nav-link" href="/language/extension-methods">Extension methods</a></li><li class="nav-item"><a class="nav-link" href="/language/extension-types">Extension types</a></li><li class="nav-item"><a class="nav-link" href="/language/callable-objects">Callable objects</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-8" href="#sidenav-1-8" role="button" aria-expanded="false" aria-controls="sidenav-1-8">Class modifiers</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-8"><li class="nav-item"><a class="nav-link" href="/language/class-modifiers">Overview & usage</a></li><li class="nav-item"><a class="nav-link" href="/language/class-modifiers-for-apis">Class modifiers for API maintainers</a></li><li class="nav-item"><a class="nav-link" href="/language/modifier-reference">Reference</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-9" href="#sidenav-1-9" role="button" aria-expanded="false" aria-controls="sidenav-1-9">Concurrency</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-9"><li class="nav-item"><a class="nav-link" href="/language/concurrency">Overview</a></li><li class="nav-item"><a class="nav-link" href="/language/async">Asynchronous support</a></li><li class="nav-item"><a class="nav-link" href="/language/isolates">Isolates</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-10" href="#sidenav-1-10" role="button" aria-expanded="false" aria-controls="sidenav-1-10">Null safety</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-10"><li class="nav-item"><a class="nav-link" href="/null-safety">Sound null safety</a></li><li class="nav-item"><a class="nav-link" href="/null-safety/migration-guide">Migrating to null safety</a></li><li class="nav-item"><a class="nav-link" href="/null-safety/understanding-null-safety">Understanding null safety</a></li><li class="nav-item"><a class="nav-link" href="/null-safety/unsound-null-safety">Unsound null safety</a></li><li class="nav-item"><a class="nav-link" href="/null-safety/faq">FAQ</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" href="#sidenav-2" role="button" aria-expanded="true" aria-controls="sidenav-2">Core libraries</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-2"><li class="nav-item"><a class="nav-link" href="/libraries">Overview</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-core">dart:core</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-async">dart:async</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-math">dart:math</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-convert">dart:convert</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-io">dart:io</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-html">dart:html</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/libraries/collections/iterables">Iterable collections</a></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" data-target="#sidenav-2-10" href="#sidenav-2-10" role="button" aria-expanded="true" aria-controls="sidenav-2-10">Asynchronous programming</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-2-10"><li class="nav-item"><a class="nav-link" href="/libraries/async/async-await">Tutorial</a></li><li class="nav-item"><a class="nav-link active" href="/libraries/async/futures-error-handling">Futures and error handling</a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/using-streams">Using streams</a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/creating-streams">Creating streams</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-3" role="button" aria-expanded="false" aria-controls="sidenav-3">Effective Dart</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-3"><li class="nav-item"><a class="nav-link" href="/effective-dart">Overview</a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/style">Style</a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/documentation">Documentation</a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/usage">Usage</a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/design">Design</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-4" role="button" aria-expanded="false" aria-controls="sidenav-4">Packages</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-4"><li class="nav-item"><a class="nav-link" href="/tools/pub/packages">How to use packages</a></li><li class="nav-item"><a class="nav-link" href="/resources/useful-packages">Commonly used packages</a></li><li class="nav-item"><a class="nav-link" href="/guides/libraries/create-packages">Creating packages</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/publishing">Publishing packages</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/writing-package-pages">Writing package pages</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-4-6" href="#sidenav-4-6" role="button" aria-expanded="false" aria-controls="sidenav-4-6">Package reference</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-4-6"><li class="nav-item"><a class="nav-link" href="/tools/pub/dependencies">Dependencies</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/glossary">Glossary</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/package-layout">Package layout conventions</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/environment-variables">Pub environment variables</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/pubspec">Pubspec file</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/troubleshoot">Troubleshooting pub</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/verified-publishers">Verified publishers</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/security-advisories">Security advisories</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/versioning">Versioning</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/custom-package-repositories">Custom package repositories</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/guides/libraries/private-files">What not to commit</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-5" role="button" aria-expanded="false" aria-controls="sidenav-5">Development</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-5"><li class="nav-item"><a class="nav-link" href="/guides/json">JSON</a></li><li class="nav-item"><a class="nav-link" href="/guides/language/numbers">Number representation</a></li><li class="nav-item"><a class="nav-link" href="/resources/google-apis">Google APIs</a></li><li class="nav-item"><a class="nav-link" href="/multiplatform-apps">Multi-platform apps</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-5" href="#sidenav-5-5" role="button" aria-expanded="false" aria-controls="sidenav-5-5">Command-line & server apps</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-5-5"><li class="nav-item"><a class="nav-link" href="/server">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/get-started">Get started</a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/cmdline">Write command-line apps</a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/fetch-data">Fetch data from the internet</a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/httpserver">Write HTTP servers</a></li><li class="nav-item"><a class="nav-link" href="/server/libraries">Libraries & packages</a></li><li class="nav-item"><a class="nav-link" href="/server/google-cloud">Google Cloud</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-6" href="#sidenav-5-6" role="button" aria-expanded="false" aria-controls="sidenav-5-6">Web apps</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/web">Overview</a></li><li class="nav-item"><a class="nav-link" href="/web/get-started">Get started</a></li><li class="nav-item"><a class="nav-link" href="/web/deployment">Deployment</a></li><li class="nav-item"><a class="nav-link" href="/web/libraries">Libraries & packages</a></li><li class="nav-item"><a class="nav-link" href="/web/wasm">Wasm compilation</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/guides/environment-declarations">Environment declarations</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-6" role="button" aria-expanded="false" aria-controls="sidenav-6">Interoperability</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-6"><li class="nav-item"><a class="nav-link" href="/interop/c-interop">C interop</a></li><li class="nav-item"><a class="nav-link" href="/interop/objective-c-interop">Objective-C & Swift interop</a></li><li class="nav-item"><a class="nav-link" href="/interop/java-interop">Java & Kotlin interop</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-6-4" href="#sidenav-6-4" role="button" aria-expanded="false" aria-controls="sidenav-6-4">JavaScript interop</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-6-4"><li class="nav-item"><a class="nav-link" href="/interop/js-interop">Overview</a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/usage">Usage</a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/js-types">JS types</a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/tutorials">Tutorials</a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/past-js-interop">Past JS interop</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/interop/js-interop/package-web">Web interop</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-7" role="button" aria-expanded="false" aria-controls="sidenav-7">Tools & techniques</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7"><li class="nav-item"><a class="nav-link" href="/tools">Overview</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-2" href="#sidenav-7-2" role="button" aria-expanded="false" aria-controls="sidenav-7-2">Editors & debuggers</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-2"><li class="nav-item"><a class="nav-link" href="/tools/jetbrains-plugin">IntelliJ & Android Studio</a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code">VS Code</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-devtools">Dart DevTools</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-2-4" href="#sidenav-7-2-4" role="button" aria-expanded="false" aria-controls="sidenav-7-2-4">DartPad</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-2-4"><li class="nav-item"><a class="nav-link" href="/tools/dartpad">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/dartpad/troubleshoot">Troubleshooting DartPad</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-3" href="#sidenav-7-3" role="button" aria-expanded="false" aria-controls="sidenav-7-3">Command-line tools</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-3"><li class="nav-item"><a class="nav-link collapsible" data-toggle="collapse" data-target="#sidenav-7-3-1" href="#sidenav-7-3-1" role="button" aria-expanded="true" aria-controls="sidenav-7-3-1">Dart SDK</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-7-3-1"><li class="nav-item"><a class="nav-link" href="/tools/sdk">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-tool">dart</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-analyze">dart analyze</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-compile">dart compile</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-create">dart create</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-doc">dart doc</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-fix">dart fix</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-format">dart format</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-info">dart info</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/cmd">dart pub</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-run">dart run</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-test">dart test</a></li><li class="nav-item"><a class="nav-link" href="/tools/dartaotruntime">dartaotruntime</a></li><li class="nav-item"><a class="nav-link" href="/tools/experiment-flags">Experiment flags</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible" data-toggle="collapse" data-target="#sidenav-7-3-2" href="#sidenav-7-3-2" role="button" aria-expanded="true" aria-controls="sidenav-7-3-2">Other command-line tools</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-7-3-2"><li class="nav-item"><a class="nav-link" href="/tools/build_runner">build_runner</a></li><li class="nav-item"><a class="nav-link" href="/tools/webdev">webdev</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-4" href="#sidenav-7-4" role="button" aria-expanded="false" aria-controls="sidenav-7-4">Static analysis</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-4"><li class="nav-item"><a class="nav-link" href="/tools/analysis">Customizing static analysis</a></li><li class="nav-item"><a class="nav-link" href="/guides/language/sound-problems">Fixing common type problems</a></li><li class="nav-item"><a class="nav-link" href="/tools/non-promotion-reasons">Fixing type promotion failures</a></li><li class="nav-item"><a class="nav-link" href="/tools/linter-rules">Linter rules</a></li><li class="nav-item"><a class="nav-link" href="/tools/diagnostic-messages">Diagnostic messages</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-5" href="#sidenav-7-5" role="button" aria-expanded="false" aria-controls="sidenav-7-5">Testing & optimization</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-5"><li class="nav-item"><a class="nav-link" href="/guides/testing">Testing</a></li><li class="nav-item"><a class="nav-link" href="/web/debugging">Debugging web apps</a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-9" role="button" aria-expanded="false" aria-controls="sidenav-9">Resources</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-9"><li class="nav-item"><a class="nav-link" href="/resources/dart-cheatsheet">Language cheatsheet</a></li><li class="nav-item"><a class="nav-link" href="/resources/breaking-changes">Breaking changes</a></li><li class="nav-item"><a class="nav-link" href="/guides/language/evolution">Language evolution</a></li><li class="nav-item"><a class="nav-link" href="/guides/language/spec">Language specification</a></li><li class="nav-item"><a class="nav-link" href="/resources/dart-3-migration">Dart 3 migration guide</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-9-6" href="#sidenav-9-6" role="button" aria-expanded="false" aria-controls="sidenav-9-6">Coming from ...</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-9-6"><li class="nav-item"><a class="nav-link" href="/resources/coming-from/js-to-dart">JavaScript to Dart</a></li><li class="nav-item"><a class="nav-link" href="/resources/coming-from/swift-to-dart">Swift to Dart</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/resources/faq">FAQ</a></li><li class="nav-item"><a class="nav-link" href="/resources/glossary">Glossary</a></li><li class="nav-item"><a class="nav-link" href="/resources/books">Books</a></li><li class="nav-item"><a class="nav-link" href="/resources/videos">Videos</a></li><li class="nav-item"><a class="nav-link" href="/tutorials">Tutorials</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible" data-toggle="collapse" href="#sidenav-10" role="button" aria-expanded="true" aria-controls="sidenav-10">Related sites</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-10"><li class="nav-item"><a class="nav-link" href="https://api.dart.dev" target="_blank" rel="noopener">API reference</a></li><li class="nav-item"><a class="nav-link" href="https://medium.com/dartlang" target="_blank" rel="noopener">Blog</a></li><li class="nav-item"><a class="nav-link" href="https://dartpad.dev" target="_blank" rel="noopener">DartPad (online editor)</a></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev" target="_blank" rel="noopener">Flutter</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev" target="_blank" rel="noopener">Package site</a></li></ul></li></ul></div></div><main id="page-content"><div id="site-toc--side" class="site-toc"><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry nav-item"><a class="nav-link" href="#the-future-api-and-callbacks">The Future API and callbacks</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#examples-of-using-then-with-catcherror">Examples of using then() with catchError()</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#catcherror-as-a-comprehensive-error-handler">catchError() as a comprehensive error handler</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#error-handling-within-then">Error handling within then()</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#errors-in-the-middle-of-a-long-chain">Errors in the middle of a long chain</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#handling-specific-errors">Handling specific errors</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#async-try-catch-finally-using-whencomplete">Async try-catch-finally using whenComplete()</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#completing-the-future-returned-by-whencomplete">Completing the Future returned by whenComplete()</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#errors-originating-within-whencomplete">Errors originating within whenComplete()</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#potential-problem-failing-to-register-error-handlers-early">Potential problem: failing to register error handlers early</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#potential-problem-accidentally-mixing-synchronous-and-asynchronous-errors">Potential problem: accidentally mixing synchronous and asynchronous errors</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#solution-using-future-sync-to-wrap-your-code">Solution: Using Future.sync() to wrap your code</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#more-information">More information</a></li></ul></div><article><div class="content"><div id="site-content-title"><h1>Futures and error handling</h1></div><div id="site-toc--inline" class="site-toc toc-collapsible toc-collapsed"><header class="site-toc__title">Contents <span class="site-toc--inline__toggle toc-toggle-down"><i class="material-symbols">keyboard_arrow_down</i></span> <span class="site-toc--inline__toggle toc-toggle-up"><i class="material-symbols">keyboard_arrow_up</i></span></header><ul class="section-nav"><li class="toc-entry"><a href="#the-future-api-and-callbacks">The Future API and callbacks</a></li><li class="toc-entry"><a href="#examples-of-using-then-with-catcherror">Examples of using then() with catchError()</a><ul><li class="toc-entry"><a href="#catcherror-as-a-comprehensive-error-handler">catchError() as a comprehensive error handler</a></li><li class="toc-entry"><a href="#error-handling-within-then">Error handling within then()</a></li><li class="toc-entry"><a href="#errors-in-the-middle-of-a-long-chain">Errors in the middle of a long chain</a></li><li class="toc-entry"><a href="#handling-specific-errors">Handling specific errors</a></li></ul></li><li class="toc-entry"><a href="#async-try-catch-finally-using-whencomplete">Async try-catch-finally using whenComplete()</a><ul><li class="toc-entry"><a href="#completing-the-future-returned-by-whencomplete">Completing the Future returned by whenComplete()</a></li><li class="toc-entry"><a href="#errors-originating-within-whencomplete">Errors originating within whenComplete()</a></li></ul></li><li class="toc-entry"><a href="#potential-problem-failing-to-register-error-handlers-early">Potential problem: failing to register error handlers early</a></li><li class="toc-entry"><a href="#potential-problem-accidentally-mixing-synchronous-and-asynchronous-errors">Potential problem: accidentally mixing synchronous and asynchronous errors</a><ul><li class="toc-entry"><a href="#solution-using-future-sync-to-wrap-your-code">Solution: Using Future.sync() to wrap your code</a></li></ul></li><li class="toc-entry"><a href="#more-information">More information</a></li></ul><span class="site-toc--inline__toggle toc-toggle-more-items"><i class="material-symbols">more_horiz</i></span></div><p>The Dart language has native <a href="/language/async">asynchrony support</a>, making asynchronous Dart code much easier to read and write. However, some code鈥攅specially older code鈥攎ight still use <a href="https://api.dart.dev/dart-async/Future-class.html">Future methods</a> such as <code>then()</code>, <code>catchError()</code>, and <code>whenComplete()</code>.</p><p>This page can help you avoid some common pitfalls when using those Future methods.</p><aside class="alert alert-warning"><div class="alert-header"><i class="material-symbols" aria-hidden="true">warning</i> <span>Warning</span></div><div class="alert-content"><p>You don't need this page if your code uses the language's asynchrony support: <code>async</code>, <code>await</code>, and error handling using try-catch. For more information, see the <a href="/libraries/async/async-await">asynchronous programming tutorial</a>.</p></div></aside><div class="header-wrapper"><h2 id="the-future-api-and-callbacks">The Future API and callbacks</h2><a class="heading-link" href="#the-future-api-and-callbacks" aria-label="Link to 'The Future API and callbacks' section">#</a></div><p>Functions that use the Future API register callbacks that handle the value (or the error) that completes a Future. For example:</p> <?code-excerpt "futures/lib/simple.dart (then-catch)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#6200EE">myFunc</span><span style="color:#222222">().</span><span style="color:#6200EE">then</span><span style="color:#222222">(processValue).</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleError);</span></span></code></pre></div></div><p>The registered callbacks fire based on the following rules: <code>then()</code>'s callback fires if it is invoked on a Future that completes with a value; <code>catchError()</code>'s callback fires if it is invoked on a Future that completes with an error.</p><p>In the example above, if <code>myFunc()</code>'s Future completes with a value, <code>then()</code>'s callback fires. If no new error is produced within <code>then()</code>, <code>catchError()</code>'s callback does not fire. On the other hand, if <code>myFunc()</code> completes with an error, <code>then()</code>'s callback does not fire, and <code>catchError()</code>'s callback does.</p><div class="header-wrapper"><h2 id="examples-of-using-then-with-catcherror">Examples of using then() with catchError()</h2><a class="heading-link" href="#examples-of-using-then-with-catcherror" aria-label="Link to 'Examples of using then() with catchError()' section">#</a></div><p>Chained <code>then()</code> and <code>catchError()</code> invocations are a common pattern when dealing with Futures, and can be thought of as the rough equivalent of try-catch blocks.</p><p>The next few sections give examples of this pattern.</p><div class="header-wrapper"><h3 id="catcherror-as-a-comprehensive-error-handler">catchError() as a comprehensive error handler</h3><a class="heading-link" href="#catcherror-as-a-comprehensive-error-handler" aria-label="Link to 'catchError() as a comprehensive error handler' section">#</a></div><p>The following example deals with throwing an exception from within <code>then()</code>'s callback and demonstrates <code>catchError()</code>'s versatility as an error handler:</p> <?code-excerpt "futures/lib/simple.dart (comprehensive-errors)" replace="/ellipsis\(\);/.../g;"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#6200EE">myFunc</span><span style="color:#222222">().</span><span style="color:#6200EE">then</span><span style="color:#222222">((value) {</span></span> <span class="line"><span style="color:#6200EE"> doSomethingWith</span><span style="color:#222222">(value);</span></span> <span class="line"><span style="color:#222222"> ...</span></span> <span class="line"><span style="color:#D43324"> throw</span><span style="color:#0468D7"> Exception</span><span style="color:#222222">(</span><span style="color:#11796D">'Some arbitrary error'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}).</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleError);</span></span></code></pre></div></div><p>If <code>myFunc()</code>'s Future completes with a value, <code>then()</code>'s callback fires. If code within <code>then()</code>'s callback throws (as it does in the example above), <code>then()</code>'s Future completes with an error. That error is handled by <code>catchError()</code>.</p><p>If <code>myFunc()</code>'s Future completes with an error, <code>then()</code>'s Future completes with that error. The error is also handled by <code>catchError()</code>.</p><p>Regardless of whether the error originated within <code>myFunc()</code> or within <code>then()</code>, <code>catchError()</code> successfully handles it.</p><div class="header-wrapper"><h3 id="error-handling-within-then">Error handling within then()</h3><a class="heading-link" href="#error-handling-within-then" aria-label="Link to 'Error handling within then()' section">#</a></div><p>For more granular error handling, you can register a second (<code>onError</code>) callback within <code>then()</code> to handle Futures completed with errors. Here is <code>then()</code>'s signature:</p> <?code-excerpt "futures/lib/simple.dart (future-then)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">R</span><span style="color:#222222">> </span><span style="color:#6200EE">then</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">R</span><span style="color:#222222">>(</span><span style="color:#0468D7">FutureOr</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">R</span><span style="color:#222222">> </span><span style="color:#0468D7">Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> value) onValue, {</span><span style="color:#0468D7">Function</span><span style="color:#222222">? onError});</span></span></code></pre></div></div><p>Register the optional onError callback only if you want to differentiate between an error forwarded <em>to</em> <code>then()</code>, and an error generated <em>within</em> <code>then()</code>:</p> <?code-excerpt "futures/lib/simple.dart (throws-then-catch)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#6200EE">asyncErrorFunction</span><span style="color:#222222">().</span><span style="color:#6200EE">then</span><span style="color:#222222">(successCallback, onError: (e) {</span></span> <span class="line"><span style="color:#6200EE"> handleError</span><span style="color:#222222">(e); </span><span style="color:#6E6E70">// Original error.</span></span> <span class="line"><span style="color:#6200EE"> anotherAsyncErrorFunction</span><span style="color:#222222">(); </span><span style="color:#6E6E70">// Oops, new error.</span></span> <span class="line"><span style="color:#222222">}).</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleError); </span><span style="color:#6E6E70">// Error from within then() handled.</span></span></code></pre></div></div><p>In the example above, <code>asyncErrorFunction()</code>'s Future's error is handled with the <code>onError</code> callback; <code>anotherAsyncErrorFunction()</code> causes <code>then()</code>'s Future to complete with an error; this error is handled by <code>catchError()</code>.</p><p>In general, implementing two different error handling strategies is not recommended: register a second callback only if there is a compelling reason to catch the error within <code>then()</code>.</p><div class="header-wrapper"><h3 id="errors-in-the-middle-of-a-long-chain">Errors in the middle of a long chain</h3><a class="heading-link" href="#errors-in-the-middle-of-a-long-chain" aria-label="Link to 'Errors in the middle of a long chain' section">#</a></div><p>It is common to have a succession of <code>then()</code> calls, and catch errors generated from any part of the chain using <code>catchError()</code>:</p> <?code-excerpt "futures/lib/long_chain.dart"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">one</span><span style="color:#222222">() => </span><span style="color:#0468D7">Future</span><span style="color:#222222">.</span><span style="color:#6200EE">value</span><span style="color:#222222">(</span><span style="color:#11796D">'from one'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">two</span><span style="color:#222222">() => </span><span style="color:#0468D7">Future</span><span style="color:#222222">.</span><span style="color:#6200EE">error</span><span style="color:#222222">(</span><span style="color:#11796D">'error from two'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">three</span><span style="color:#222222">() => </span><span style="color:#0468D7">Future</span><span style="color:#222222">.</span><span style="color:#6200EE">value</span><span style="color:#222222">(</span><span style="color:#11796D">'from three'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">four</span><span style="color:#222222">() => </span><span style="color:#0468D7">Future</span><span style="color:#222222">.</span><span style="color:#6200EE">value</span><span style="color:#222222">(</span><span style="color:#11796D">'from four'</span><span style="color:#222222">);</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> one</span><span style="color:#222222">() </span><span style="color:#6E6E70">// Future completes with "from one".</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">((_) => </span><span style="color:#6200EE">two</span><span style="color:#222222">()) </span><span style="color:#6E6E70">// Future completes with two()'s error.</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">((_) => </span><span style="color:#6200EE">three</span><span style="color:#222222">()) </span><span style="color:#6E6E70">// Future completes with two()'s error.</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">((_) => </span><span style="color:#6200EE">four</span><span style="color:#222222">()) </span><span style="color:#6E6E70">// Future completes with two()'s error.</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">((value) => value.length) </span><span style="color:#6E6E70">// Future completes with two()'s error.</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">((e) {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Got error: </span><span style="color:#11796D">$</span><span style="color:#222222">e</span><span style="color:#11796D">'</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Finally, callback fires.</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#11796D"> 42</span><span style="color:#222222">; </span><span style="color:#6E6E70">// Future completes with 42.</span></span> <span class="line"><span style="color:#222222"> }).</span><span style="color:#6200EE">then</span><span style="color:#222222">((value) {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'The value is </span><span style="color:#11796D">$</span><span style="color:#222222">value</span><span style="color:#11796D">'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70">// Output of this program:</span></span> <span class="line"><span style="color:#6E6E70">// Got error: error from two</span></span> <span class="line"><span style="color:#6E6E70">// The value is 42</span></span></code></pre></div></div><p>In the code above, <code>one()</code>'s Future completes with a value, but <code>two()</code>'s Future completes with an error. When <code>then()</code> is invoked on a Future that completes with an error, <code>then()</code>'s callback does not fire. Instead, <code>then()</code>'s Future completes with the error of its receiver. In our example, this means that after <code>two()</code> is called, the Future returned by every subsequent <code>then()</code>completes with <code>two()</code>'s error. That error is finally handled within <code>catchError()</code>.</p><div class="header-wrapper"><h3 id="handling-specific-errors">Handling specific errors</h3><a class="heading-link" href="#handling-specific-errors" aria-label="Link to 'Handling specific errors' section">#</a></div><p>What if we want to catch a specific error? Or catch more than one error?</p><p><code>catchError()</code> takes an optional named argument, <code>test</code>, that allows us to query the kind of error thrown.</p> <?code-excerpt "futures/lib/simple.dart (future-catch-error)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">catchError</span><span style="color:#222222">(</span><span style="color:#0468D7">Function</span><span style="color:#222222"> onError, {</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">Object</span><span style="color:#222222"> error)? test});</span></span></code></pre></div></div><p>Consider <code>handleAuthResponse(params)</code>, a function that authenticates a user based on the params provided, and redirects the user to an appropriate URL. Given the complex workflow, <code>handleAuthResponse()</code> could generate various errors and exceptions, and you should handle them differently. Here's how you can use <code>test</code> to do that:</p> <?code-excerpt "futures/lib/simple.dart (auth-response)" replace="/ellipsis\(\)/.../g;"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> handleAuthResponse</span><span style="color:#222222">(</span><span style="color:#D43324">const</span><span style="color:#222222"> {</span><span style="color:#11796D">'username'</span><span style="color:#222222">: </span><span style="color:#11796D">'dash'</span><span style="color:#222222">, </span><span style="color:#11796D">'age'</span><span style="color:#222222">: </span><span style="color:#11796D">3</span><span style="color:#222222">})</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">((_) => ...)</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleFormatException, test: (e) => e is </span><span style="color:#0468D7">FormatException</span><span style="color:#222222">)</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleAuthorizationException,</span></span> <span class="line"><span style="color:#222222"> test: (e) => e is </span><span style="color:#0468D7">AuthorizationException</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="async-try-catch-finally-using-whencomplete">Async try-catch-finally using whenComplete()</h2><a class="heading-link" href="#async-try-catch-finally-using-whencomplete" aria-label="Link to 'Async try-catch-finally using whenComplete()' section">#</a></div><p>If <code>then().catchError()</code> mirrors a try-catch, <code>whenComplete()</code> is the equivalent of 'finally'. The callback registered within <code>whenComplete()</code> is called when <code>whenComplete()</code>'s receiver completes, whether it does so with a value or with an error:</p> <?code-excerpt "futures/lib/simple.dart (connect-server)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">final</span><span style="color:#222222"> server = </span><span style="color:#6200EE">connectToServer</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222">server</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">post</span><span style="color:#222222">(myUrl, fields: </span><span style="color:#D43324">const</span><span style="color:#222222"> {</span><span style="color:#11796D">'name'</span><span style="color:#222222">: </span><span style="color:#11796D">'Dash'</span><span style="color:#222222">, </span><span style="color:#11796D">'profession'</span><span style="color:#222222">: </span><span style="color:#11796D">'mascot'</span><span style="color:#222222">})</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">(handleResponse)</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleError)</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">whenComplete</span><span style="color:#222222">(server.close);</span></span></code></pre></div></div><p>We want to call <code>server.close</code> regardless of whether <code>server.post()</code> produces a valid response, or an error. We ensure this happens by placing it inside <code>whenComplete()</code>.</p><div class="header-wrapper"><h3 id="completing-the-future-returned-by-whencomplete">Completing the Future returned by whenComplete()</h3><a class="heading-link" href="#completing-the-future-returned-by-whencomplete" aria-label="Link to 'Completing the Future returned by whenComplete()' section">#</a></div><p>If no error is emitted from within <code>whenComplete()</code>, its Future completes the same way as the Future that <code>whenComplete()</code> is invoked on. This is easiest to understand through examples.</p><p>In the code below, <code>then()</code>'s Future completes with an error, so <code>whenComplete()</code>'s Future also completes with that error.</p> <?code-excerpt "futures/lib/when_complete.dart (with-error)" replace="/withErrorMain/main/g; "?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> asyncErrorFunction</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#6E6E70"> // Future completes with an error:</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">((_) => </span><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">"Won't reach here"</span><span style="color:#222222">))</span></span> <span class="line"><span style="color:#6E6E70"> // Future completes with the same error:</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">whenComplete</span><span style="color:#222222">(() => </span><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">'Reaches here'</span><span style="color:#222222">))</span></span> <span class="line"><span style="color:#6E6E70"> // Future completes with the same error:</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">((_) => </span><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">"Won't reach here"</span><span style="color:#222222">))</span></span> <span class="line"><span style="color:#6E6E70"> // Error is handled here:</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleError);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>In the code below, <code>then()</code>'s Future completes with an error, which is now handled by <code>catchError()</code>. Because <code>catchError()</code>'s Future completes with <code>someObject</code>, <code>whenComplete()</code>'s Future completes with that same object.</p> <?code-excerpt "futures/lib/when_complete.dart (with-object)" replace="/ellipsis\(\)/.../g; /withObjectMain/main/g; "?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> asyncErrorFunction</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#6E6E70"> // Future completes with an error:</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">((_) => ...)</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">((e) {</span></span> <span class="line"><span style="color:#6200EE"> handleError</span><span style="color:#222222">(e);</span></span> <span class="line"><span style="color:#6200EE"> printErrorMessage</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> someObject; </span><span style="color:#6E6E70">// Future completes with someObject</span></span> <span class="line"><span style="color:#222222"> }).</span><span style="color:#6200EE">whenComplete</span><span style="color:#222222">(() => </span><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">'Done!'</span><span style="color:#222222">)); </span><span style="color:#6E6E70">// Future completes with someObject</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="errors-originating-within-whencomplete">Errors originating within whenComplete()</h3><a class="heading-link" href="#errors-originating-within-whencomplete" aria-label="Link to 'Errors originating within whenComplete()' section">#</a></div><p>If <code>whenComplete()</code>'s callback throws an error, then <code>whenComplete()</code>'s Future completes with that error:</p> <?code-excerpt "futures/lib/when_complete.dart (when-complete-error)" replace="/whenCompleteError/main/g; "?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> asyncErrorFunction</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#6E6E70"> // Future completes with a value:</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleError)</span></span> <span class="line"><span style="color:#6E6E70"> // Future completes with an error:</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">whenComplete</span><span style="color:#222222">(() => </span><span style="color:#D43324">throw</span><span style="color:#0468D7"> Exception</span><span style="color:#222222">(</span><span style="color:#11796D">'New error'</span><span style="color:#222222">))</span></span> <span class="line"><span style="color:#6E6E70"> // Error is handled:</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(handleError);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="potential-problem-failing-to-register-error-handlers-early">Potential problem: failing to register error handlers early</h2><a class="heading-link" href="#potential-problem-failing-to-register-error-handlers-early" aria-label="Link to 'Potential problem: failing to register error handlers early' section">#</a></div><p>It is crucial that error handlers are installed before a Future completes: this avoids scenarios where a Future completes with an error, the error handler is not yet attached, and the error accidentally propagates. Consider this code:</p> <?code-excerpt "futures/lib/early_error_handlers.dart (bad)" replace="/ellipsis\(\)/.../g; /mainBad/main/g;"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Object</span><span style="color:#222222">> future = </span><span style="color:#6200EE">asyncErrorFunction</span><span style="color:#222222">();</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // BAD: Too late to handle asyncErrorFunction() exception.</span></span> <span class="line"><span style="color:#0468D7"> Future</span><span style="color:#222222">.</span><span style="color:#6200EE">delayed</span><span style="color:#222222">(</span><span style="color:#D43324">const</span><span style="color:#0468D7"> Duration</span><span style="color:#222222">(milliseconds: </span><span style="color:#11796D">500</span><span style="color:#222222">), () {</span></span> <span class="line"><span style="color:#222222"> future.</span><span style="color:#6200EE">then</span><span style="color:#222222">(...).</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(...);</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>In the code above, <code>catchError()</code> is not registered until half a second after <code>asyncErrorFunction()</code> is called, and the error goes unhandled.</p><p>The problem goes away if <code>asyncErrorFunction()</code> is called within the <code>Future.delayed()</code> callback:</p> <?code-excerpt "futures/lib/early_error_handlers.dart (good)" replace="/ellipsis\(\)/.../g; /mainGood/main/g;"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> Future</span><span style="color:#222222">.</span><span style="color:#6200EE">delayed</span><span style="color:#222222">(</span><span style="color:#D43324">const</span><span style="color:#0468D7"> Duration</span><span style="color:#222222">(milliseconds: </span><span style="color:#11796D">500</span><span style="color:#222222">), () {</span></span> <span class="line"><span style="color:#6200EE"> asyncErrorFunction</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">then</span><span style="color:#222222">(...)</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">catchError</span><span style="color:#222222">(...); </span><span style="color:#6E6E70">// We get here.</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="potential-problem-accidentally-mixing-synchronous-and-asynchronous-errors">Potential problem: accidentally mixing synchronous and asynchronous errors</h2><a class="heading-link" href="#potential-problem-accidentally-mixing-synchronous-and-asynchronous-errors" aria-label="Link to 'Potential problem: accidentally mixing synchronous and asynchronous errors' section">#</a></div><p>Functions that return Futures should almost always emit their errors in the future. Since we do not want the caller of such functions to have to implement multiple error-handling scenarios, we want to prevent any synchronous errors from leaking out. Consider this code:</p> <?code-excerpt "futures/bin/mixing_errors_problematic.dart (parse)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">int</span><span style="color:#222222">> </span><span style="color:#6200EE">parseAndRead</span><span style="color:#222222">(</span><span style="color:#0468D7">Map</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">dynamic</span><span style="color:#222222">> data) {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> filename = </span><span style="color:#6200EE">obtainFilename</span><span style="color:#222222">(data); </span><span style="color:#6E6E70">// Could throw.</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> file = </span><span style="color:#0468D7">File</span><span style="color:#222222">(filename);</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> file.</span><span style="color:#6200EE">readAsString</span><span style="color:#222222">().</span><span style="color:#6200EE">then</span><span style="color:#222222">((contents) {</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#6200EE"> parseFileData</span><span style="color:#222222">(contents); </span><span style="color:#6E6E70">// Could throw.</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Two functions in that code could potentially throw synchronously: <code>obtainFilename()</code> and <code>parseFileData()</code>. Because <code>parseFileData()</code> executes inside a <code>then()</code> callback, its error does not leak out of the function. Instead, <code>then()</code>'s Future completes with <code>parseFileData()</code>'s error, the error eventually completes <code>parseAndRead()</code>'s Future, and the error can be successfully handled by <code>catchError()</code>.</p><p>But <code>obtainFilename()</code> is not called within a <code>then()</code> callback; if <em>it</em> throws, a synchronous error propagates:</p> <?code-excerpt "futures/bin/mixing_errors_problematic.dart (main)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> parseAndRead</span><span style="color:#222222">(data).</span><span style="color:#6200EE">catchError</span><span style="color:#222222">((e) {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Inside catchError'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(e);</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> -</span><span style="color:#11796D">1</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70">// Program Output:</span></span> <span class="line"><span style="color:#6E6E70">// Unhandled exception:</span></span> <span class="line"><span style="color:#6E6E70">// &#x3C;error from obtainFilename></span></span> <span class="line"><span style="color:#6E6E70">// ...</span></span></code></pre></div></div><p>Because using <code>catchError()</code> does not capture the error, a client of <code>parseAndRead()</code> would implement a separate error-handling strategy for this error.</p><div class="header-wrapper"><h3 id="solution-using-future-sync-to-wrap-your-code">Solution: Using Future.sync() to wrap your code</h3><a class="heading-link" href="#solution-using-future-sync-to-wrap-your-code" aria-label="Link to 'Solution: Using Future.sync() to wrap your code' section">#</a></div><p>A common pattern for ensuring that no synchronous error is accidentally thrown from a function is to wrap the function body inside a new <code>Future.sync()</code> callback:</p> <?code-excerpt "futures/bin/mixing_errors_solution.dart (parse)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">int</span><span style="color:#222222">> </span><span style="color:#6200EE">parseAndRead</span><span style="color:#222222">(</span><span style="color:#0468D7">Map</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">dynamic</span><span style="color:#222222">> data) {</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#0468D7"> Future</span><span style="color:#222222">.</span><span style="color:#D43324">sync</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> filename = </span><span style="color:#6200EE">obtainFilename</span><span style="color:#222222">(data); </span><span style="color:#6E6E70">// Could throw.</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> file = </span><span style="color:#0468D7">File</span><span style="color:#222222">(filename);</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> file.</span><span style="color:#6200EE">readAsString</span><span style="color:#222222">().</span><span style="color:#6200EE">then</span><span style="color:#222222">((contents) {</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#6200EE"> parseFileData</span><span style="color:#222222">(contents); </span><span style="color:#6E6E70">// Could throw.</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>If the callback returns a non-Future value, <code>Future.sync()</code>'s Future completes with that value. If the callback throws (as it does in the example above), the Future completes with an error. If the callback itself returns a Future, the value or the error of that Future completes <code>Future.sync()</code>'s Future.</p><p>With code wrapped within <code>Future.sync()</code>, <code>catchError()</code> can handle all errors:</p> <?code-excerpt "futures/bin/mixing_errors_solution.dart (main)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> parseAndRead</span><span style="color:#222222">(data).</span><span style="color:#6200EE">catchError</span><span style="color:#222222">((e) {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Inside catchError'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(e);</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> -</span><span style="color:#11796D">1</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70">// Program Output:</span></span> <span class="line"><span style="color:#6E6E70">// Inside catchError</span></span> <span class="line"><span style="color:#6E6E70">// &#x3C;error from obtainFilename></span></span></code></pre></div></div><p><code>Future.sync()</code> makes your code resilient against uncaught exceptions. If your function has a lot of code packed into it, chances are that you could be doing something dangerous without realizing it:</p> <?code-excerpt "futures/bin/mixing_errors_problematic.dart (fragile)" replace="/ellipsis\(\);/.../g;"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#6200EE"> fragileFunc</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#0468D7"> Future</span><span style="color:#222222">.</span><span style="color:#D43324">sync</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> x = </span><span style="color:#6200EE">someFunc</span><span style="color:#222222">(); </span><span style="color:#6E6E70">// Unexpectedly throws in some rare cases.</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> y = </span><span style="color:#11796D">10</span><span style="color:#222222"> / x; </span><span style="color:#6E6E70">// x should not equal 0.</span></span> <span class="line"><span style="color:#222222"> ...</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p><code>Future.sync()</code> not only allows you to handle errors you know might occur, but also prevents errors from <em>accidentally</em> leaking out of your function.</p><div class="header-wrapper"><h2 id="more-information">More information</h2><a class="heading-link" href="#more-information" aria-label="Link to 'More information' section">#</a></div><p>See the <a href="https://api.dart.dev/dart-async/Future-class.html">Future API reference</a> for more information on Futures.</p><p id="page-github-links"><span>Unless stated otherwise, the documentation on this site reflects Dart 3.5.4. Page last updated on 2024-11-17.</span> <a href="https://github.com/dart-lang/site-www/tree/main/src/content/libraries/async/futures-error-handling.md" target="_blank" rel="noopener">View source</a> <span>or </span><a href="https://github.com/dart-lang/site-www/issues/new?template=1_page_issue.yml&page-url=https://dart.dev/libraries/async/futures-error-handling/&page-source=https://github.com/dart-lang/site-www/tree/main/src/content/libraries/async/futures-error-handling.md" title="Report an issue with this page" target="_blank" rel="noopener">report an issue</a>.</p></div></article></main><footer id="page-footer"><div class="footer-section footer-main"><a href="/" class="brand" title="Dart"><img src="/assets/img/logo/logo-white-text.svg" alt="Dart" width="164"></a><div class="footer-social-links"><a href="https://medium.com/dartlang" target="_blank" rel="noopener" title="Medium blog"><svg><use href="/assets/img/social/medium.svg#medium"></use></svg> </a><a href="https://github.com/dart-lang" target="_blank" rel="noopener" title="GitHub"><svg><use href="/assets/img/social/github.svg#github"></use></svg> </a><a href="https://twitter.com/dart_lang" target="_blank" rel="noopener" title="X (Twitter)"><svg><use href="/assets/img/social/x.svg#x"></use></svg></a></div></div><div class="footer-section footer-tray"><div class="footer-licenses">Except as otherwise noted, this site is licensed under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>, and code samples are licensed under the <a href="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</a>.</div><div class="footer-utility-links"><ul><li><a href="/terms" title="Terms of use">Terms</a></li><li><a href="https://policies.google.com/privacy" target="_blank" rel="noopener" title="Privacy policy">Privacy</a></li><li><a href="/security" title="Security philosophy and practices">Security</a></li></ul></div></div></footer></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10