CINXE.COM
<!DOCTYPE html><html lang="ja" data-theme-enabled="1"><head><script>window.currentUser = null;</script><script>window.shopCurrency = "EUR";</script><script>window.localCurrency = "JPY";</script><script>window.countryCode = "us";</script><script>window.rateShopTo = {"JPY":162.38331879775942,"EUR":1,"USD":1.0874494200088518,"AMD":424.1827578369761};</script><title itemprop="name">エラーハンドリング, "try..catch"</title><link href="/pack/styles.67c491fae690f87b1f9f.css" rel="stylesheet"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes, minimum-scale=1.0"><meta name="apple-mobile-web-app-capable" content="yes"><!-- chrome autotranslate is enabled only for "en" main version--><meta name="google" content="notranslate"><script>if (window.devicePixelRatio > 1) document.cookie = 'pixelRatio=' + window.devicePixelRatio + ';path=/;expires=Tue, 19 Jan 2038 03:14:07 GMT';</script><link href="//fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic" rel="stylesheet"><link rel="apple-touch-icon-precomposed" href="/img/favicon/apple-touch-icon-precomposed.png"><link rel="canonical" href="https://ja.javascript.info/try-catch"><meta name="msapplication-TileColor" content="#222A2C"><meta name="msapplication-TileImage" content="/img/favicon/tileicon.png"><link rel="icon" href="/img/favicon/favicon.png"><meta itemprop="image" content="https://ja.javascript.info/img/site_preview_en_512x512.png"><meta property="og:title" content="エラーハンドリング, "try..catch""><meta property="og:image" content="https://ja.javascript.info/img/site_preview_en_1200x630.png"><meta property="og:image:type" content="image/png"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta property="fb:admins" content="100001562528165"><meta name="twitter:card" content="summary"><meta name="twitter:title" content="エラーハンドリング, "try..catch""><meta name="twitter:site" content="@iliakan"><meta name="twitter:creator" content="@iliakan"><meta name="twitter:image" content="https://ja.javascript.info/img/site_preview_en_512x512.png"><meta name="google-adsense-account" content="ca-pub-6204518652652613"><link rel="prev" href="/error-handling"><link rel="next" href="/custom-errors"><script data-collect-dnt="true" async src="https://scripts.simpleanalyticscdn.com/latest.js"></script><script>window.GA_ID = "UA-2056213-15";</script><script>window.YANDEX_METRIKA_ID = 32184394;</script><script>{function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-2LWB61WGYJ")}</script> <script async src="https://www.googletagmanager.com/gtag/js?id=G-2LWB61WGYJ"></script><script>window.metrika={reachGoal:function(){}},window.yandex_metrika_callbacks=[function(){try{window.metrika=new Ya.Metrika({id:YANDEX_METRIKA_ID,webvisor:!0,clickmap:!0,params:{user:window.currentUser&&window.currentUser.id}}),metrika.trackLinks({delay:150}),window.addEventListener("error",function(r){window.metrika.reachGoal("JSERROR",{src:(r.filename||r.errorUrl)+": "+(r.lineno||r.errorLine),stack:r.stack||r.error&&r.error.stack,message:r.message})})}catch(r){}}];</script><script src="//mc.yandex.ru/metrika/watch.js" async></script><script>window.RECAPTCHA_ID = "6LfmLAEVAAAAAJMykMnf7aY8nkyTRmYi2ynx51R1";</script><script src="/pack/init.9d0331bb294e70c56db9.js"></script><script src="/pack/head.3c336e1939c677aeed65.js" defer></script><meta property="og:title" content="エラーハンドリング, "try..catch""><meta property="og:type" content="article"><script src="/pack/tutorial.2da25d21c2b13cad643f.js" defer></script><script src="/pack/footer.4d7a62439a3935a4745e.js" defer></script></head><body class="no-icons"><script>window.fontTest();</script><div class="page-wrapper page-wrapper_sidebar_on"><!--[if IE]><div style="color:red;text-align:center">申し訳ありません、Internet Explorer はサポートしていないため新しいブラウザを使用してください。</div><![endif]--><div class="sitetoolbar sitetoolbar_tutorial"><script>window.langs = [{"code":"ar","name":"Arabic"},{"code":"az","name":"Azerbaijani"},{"code":"bg","name":"Bulgarian"},{"code":"bn","name":"Bengali"},{"code":"bs","name":"Bosnian"},{"code":"ca","name":"Catalan"},{"code":"cs","name":"Czech"},{"code":"da","name":"Danish"},{"code":"de","name":"German"},{"code":"el","name":"Greek"},{"code":"en","name":"English"},{"code":"es","name":"Spanish"},{"code":"fa","name":"Persian (Farsi)"},{"code":"fi","name":"Finnish"},{"code":"fr","name":"French"},{"code":"he","name":"Hebrew"},{"code":"hi","name":"Hindi"},{"code":"hr","name":"Croatian"},{"code":"hu","name":"Hungarian"},{"code":"hy","name":"Armenian"},{"code":"id","name":"Indonesian"},{"code":"it","name":"Italian"},{"code":"ja","name":"Japanese"},{"code":"ka","name":"Georgian"},{"code":"kk","name":"Kazakh"},{"code":"km","name":"Central Khmer"},{"code":"ko","name":"Korean"},{"code":"ku","name":"Kurdish"},{"code":"ky","name":"Kyrgyz"},{"code":"lt","name":"Lithuanian"},{"code":"me","name":"Montenegrin"},{"code":"ml","name":"Malayalam"},{"code":"ms","name":"Malay"},{"code":"my","name":"Burmese"},{"code":"nl","name":"Dutch"},{"code":"no","name":"Norvegian"},{"code":"pa","name":"Punjabi"},{"code":"pl","name":"Polish"},{"code":"pt","name":"Portuguese"},{"code":"ro","name":"Romanian"},{"code":"ru","name":"Russian"},{"code":"si","name":"Sinhala"},{"code":"sk","name":"Slovak"},{"code":"sl","name":"Slovenian"},{"code":"sq","name":"Albanian"},{"code":"sr","name":"Serbian"},{"code":"ta","name":"Tamil"},{"code":"te","name":"Telugu"},{"code":"test","name":"Test"},{"code":"th","name":"Thai"},{"code":"tk","name":"Turkmen"},{"code":"tr","name":"Turkish"},{"code":"ug","name":"Uyghur"},{"code":"uk","name":"Ukrainian"},{"code":"ur","name":"Urdu"},{"code":"uz","name":"Uzbek"},{"code":"v2","name":"v2"},{"code":"vi","name":"Vietnamese"},{"code":"zh-hant","name":"Chinese Traditional"},{"code":"zh","name":"Chinese"}];</script><script>window.lang = "ja";</script><div class="sitetoolbar__content"><div class="sitetoolbar__lang-switcher"><button class="sitetoolbar__dropdown-button" data-dropdown-toggler>JA</button><div class="sitetoolbar__dropdown-wrap"><div class="sitetoolbar__dropdown-body"><div class="sitetoolbar__lang-switcher-body"><div class="supported-langs supported-langs_toolbar"><div class="supported-langs__container"><ul class="supported-langs__list" style="height:200px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://ar.javascript.info/try-catch"><span class="supported-langs__brief">AR</span><span class="supported-langs__title">عربي</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://javascript.info/try-catch"><span class="supported-langs__brief">EN</span><span class="supported-langs__title">English</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://es.javascript.info/try-catch"><span class="supported-langs__brief">ES</span><span class="supported-langs__title">Español</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://fa.javascript.info/try-catch"><span class="supported-langs__brief">FA</span><span class="supported-langs__title">فارسی</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://fr.javascript.info/try-catch"><span class="supported-langs__brief">FR</span><span class="supported-langs__title">Français</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://id.javascript.info/try-catch"><span class="supported-langs__brief">ID</span><span class="supported-langs__title">Indonesia</span></a></li></ul><ul class="supported-langs__list" style="height:200px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://it.javascript.info/try-catch"><span class="supported-langs__brief">IT</span><span class="supported-langs__title">Italiano</span></a></li><li class="supported-langs__item supported-langs__item_current"><a class="supported-langs__link" href="https://ja.javascript.info/try-catch"><span class="supported-langs__brief">JA</span><span class="supported-langs__title">日本語</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://ko.javascript.info/try-catch"><span class="supported-langs__brief">KO</span><span class="supported-langs__title">한국어</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://learn.javascript.ru/try-catch"><span class="supported-langs__brief">RU</span><span class="supported-langs__title">Русский</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://tr.javascript.info/try-catch"><span class="supported-langs__brief">TR</span><span class="supported-langs__title">Türkçe</span></a></li><li class="supported-langs__item"><a class="supported-langs__link" href="https://uk.javascript.info/try-catch"><span class="supported-langs__brief">UK</span><span class="supported-langs__title">Українська</span></a></li></ul><ul class="supported-langs__list" style="height:20px"><li class="supported-langs__item"><a class="supported-langs__link" href="https://zh.javascript.info/try-catch"><span class="supported-langs__brief">ZH</span><span class="supported-langs__title">简体中文</span></a></li></ul></div><div class="supported-langs__text">私たちはこのオープンソースプロジェクトを世界中の人々に提供したいと考えています。このチュートリアルの内容をあなたが知っている言語に<a href="https://javascript.info/translate#help" rel="noopener noreferrer" target="_blank">翻訳するのを手伝って</a>ください。</div></div></div></div></div></div><div class="sitetoolbar__logo-wrap"><a class="sitetoolbar__link sitetoolbar__link_logo" href="/"><img class="sitetoolbar__logo sitetoolbar__logo_normal" src="/img/sitetoolbar__logo_en.svg" width="200" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_normal sitetoolbar__logo_dark" src="/img/sitetoolbar__logo_en-white.svg" width="200" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_small" src="/img/sitetoolbar__logo_small_en.svg" width="70" alt="" role="presentation"/><img class="sitetoolbar__logo sitetoolbar__logo_small sitetoolbar__logo_dark" src="/img/sitetoolbar__logo_small_en-white.svg" width="70" alt="" role="presentation"/><script>Array.prototype.forEach.call(document.querySelectorAll("img.sitetoolbar__logo"),function(e){let t=document.createElement("object");t.type="image/svg+xml",t.className=e.className,t.style.cssText="left:0;top:0;position:absolute",t.onload=function(){t.onload=null,e.style.visibility="hidden"},t.data=e.src,e.parentNode.insertBefore(t,e)});</script></a></div><div class="sitetoolbar__nav-toggle-wrap"><button class="sitetoolbar__nav-toggle" type="button"></button></div><nav class="sitetoolbar__sections"><ul class="sitetoolbar__sections-list"></ul></nav><div class="sitetoolbar__right-button-wrap"><a class="sitetoolbar-right-button sitetoolbar-right-button_courses" href="/ebook"><span class="sitetoolbar-right-button__extra-text">購入する</span>EPUB/PDF</a></div><div class="sitetoolbar__theme-switcher"><div class="theme-changer"><label class="theme-changer__label" for="theme-changer-input" data-tooltip="Change theme"><input class="theme-changer__input" type="checkbox" id="theme-changer-input" data-theme-changer="data-theme-changer"/><span class="theme-changer__icon theme-changer__icon_light-theme"></span><span class="theme-changer__icon theme-changer__icon_dark-theme"></span></label></div></div><div class="sitetoolbar__search-wrap"><div class="sitetoolbar__search-content"><button class="sitetoolbar__search-toggle" type="button"></button><form class="sitetoolbar__search" method="GET" action="/search"><div class="sitetoolbar__search-input"><div class="text-input"><input class="text-input__control" name="query" placeholder="チュートリアル内を検索" required="required" type="text"/></div><button class="sitetoolbar__find" type="submit">検索</button></div></form></div></div></div><div class="tablet-menu"><div class="tablet-menu__line"><div class="tablet-menu__content"><form class="tablet-menu-search" action="/search/"><input class="tablet-menu-search__input" type="search" name="query" placeholder="チュートリアル内を検索" required="required"/><button class="tablet-menu-search__button" type="submit" name="type" value="articles">検索</button></form></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><a class="map" href="/tutorial/map" data-action="tutorial-map"><span class="map__text">チュートリアルマップ</span></a></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><div class="theme-changer theme-changer_tablet-menu theme-changer_has-label"><label class="theme-changer__label" for="theme-changer-input-tablet" data-tooltip="Change theme"><input class="theme-changer__input" type="checkbox" id="theme-changer-input-tablet" data-theme-changer="data-theme-changer"/><span class="theme-changer__icon theme-changer__icon_light-theme"></span><span class="theme-changer__icon theme-changer__icon_dark-theme"></span><span class="theme-changer__label-text theme-changer__label-text_light-theme">Light theme</span><span class="theme-changer__label-text theme-changer__label-text_dark-theme">Dark theme</span></label></div></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><div class="share-icons"><span class="share-icons__title">シェア</span><a class="share share_tw" href="https://twitter.com/share?url=https%3A%2F%2Fja.javascript.info%2Ftry-catch" rel="nofollow"></a><a class="share share_fb" href="https://www.facebook.com/sharer/sharer.php?s=100&p%5Burl%5D=https%3A%2F%2Fja.javascript.info%2Ftry-catch" rel="nofollow"></a></div></div></div><div class="tablet-menu__line"><div class="tablet-menu__content"><select class="tablet-menu__nav input-select input-select input-select_small" onchange="if(this.value) window.location.href=this.value"><option value="https://ar.javascript.info/try-catch">عربي</option><option value="https://javascript.info/try-catch">English</option><option value="https://es.javascript.info/try-catch">Español</option><option value="https://fa.javascript.info/try-catch">فارسی</option><option value="https://fr.javascript.info/try-catch">Français</option><option value="https://id.javascript.info/try-catch">Indonesia</option><option value="https://it.javascript.info/try-catch">Italiano</option><option value="https://ja.javascript.info/try-catch" selected>日本語</option><option value="https://ko.javascript.info/try-catch">한국어</option><option value="https://learn.javascript.ru/try-catch">Русский</option><option value="https://tr.javascript.info/try-catch">Türkçe</option><option value="https://uk.javascript.info/try-catch">Українська</option><option value="https://zh.javascript.info/try-catch">简体中文</option></select></div></div></div><progress class="tutorial-progress" data-sticky value="73" max="92" data-tooltip="レッスン 73 of 92"></progress></div><div class="page page_sidebar_on page_inner_padding"><script>if(localStorage.noSidebar){document.querySelector(".page").classList.remove("page_sidebar_on");let e=document.querySelector(".page-wrapper");e&&e.classList.remove("page-wrapper_sidebar_on")}setTimeout(function(){document.querySelector(".page").classList.add("page_sidebar-animation-on")});</script><div class="page__inner"><main class="main main_width-limit"><header class="main__header"><div class="main__header-inner"><div class="main__header-group"><ol class="breadcrumbs"><li class="breadcrumbs__item breadcrumbs__item_home"><a class="breadcrumbs__link" href="/"><span class="breadcrumbs__hidden-text">チュートリアル</span></a></li><li class="breadcrumbs__item" id="breadcrumb-1"><a class="breadcrumbs__link" href="/js"><span>JavaScript 言語</span></a></li><li class="breadcrumbs__item" id="breadcrumb-2"><a class="breadcrumbs__link" href="/error-handling"><span>エラーハンドリング</span></a></li><script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"チュートリアル","item":"https://ja.javascript.info/"},{"@type":"ListItem","position":2,"name":"JavaScript 言語","item":"https://ja.javascript.info/js"},{"@type":"ListItem","position":3,"name":"エラーハンドリング","item":"https://ja.javascript.info/error-handling"}]}</script></ol><div class="updated-at" data-tooltip="最終更新日2024年6月23日"><div class="updated-at__content">2024年6月23日</div></div></div><h1 class="main__header-title">エラーハンドリング, "try..catch"</h1></div></header><div class="content"><article class="formatted" itemscope itemtype="http://schema.org/TechArticle"><meta itemprop="name" content="エラーハンドリング, "try..catch""><div itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="email" content="iliakan@gmail.com"><meta itemprop="name" content="Ilya Kantor"></div><div itemprop="articleBody"><p>どんなに我々のプログラミングが素晴らしくても、スクリプトがエラーになることはあります。それはミス、予期しないユーザ入力、間違ったサーバレスポンスやその他多くの理由により発生する可能性があります。</p> <p>通常、エラーが発生するとスクリプトは “死” (即時に停止) に、それをコンソールに出力します。</p> <p>しかし、エラーを “キャッチ” し、死ぬ代わりにより意味のあることをする構文構造 <code>try..catch</code> があります。</p> <h2><a class="main__anchor" name="ref-1218" href="#ref-1218">“try…catch” 構文</a></h2><p><code>try..catch</code> 構造は2つのメインブロックを持っています: <code>try</code> と <code>catch</code> です。:</p> <div id="r0libjevj4" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { // code... } catch (err) { // error handling }</code></pre> </div> </div> </div><p>それは次のように動作します:</p> <ol> <li>まず、<code>try {...}</code> のコードが実行されます。</li> <li>エラーがなければ、<code>catch(err)</code> は無視されます: 実行が <code>try</code> の最後に到達した後、<code>catch</code> を飛び越えます。</li> <li>エラーが発生した場合、<code>try</code> の実行が停止し、コントロールフローは <code>catch(err)</code> の先頭になります。<code>err</code> 変数(任意の名前が使えます)は発生した事象に関する詳細をもつエラーオブジェクトを含んでいます。</li> </ol> <figure><div class="image" style="width:514px"> <div class="image__ratio" style="padding-top:79.96108949416343%"></div> <object type="image/svg+xml" data="/article/try-catch/try-catch-flow.svg" width="514" height="411" class="image__image" data-use-theme> <img src="/article/try-catch/try-catch-flow.svg" alt="" width="514" height="411"> </object> </div></figure><p>従って、<code>try {…}</code> ブロックの内側のエラーはスクリプトを殺しません: <code>catch</code> の中でそれを扱う機会が持てます。</p> <p>いくつか例を見てみましょう。</p> <ul> <li> <p>エラーなしの例: <code>alert</code> <code>(1)</code> と <code>(2)</code> を表示します:</p> <div id="6zqde2bld2" data-trusted="1" class="code-example" data-highlight="[{"start":6,"cols":[{"start":33,"end":40}]},{"start":2,"cols":[{"start":34,"end":41}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { alert('Start of try runs'); // (1) <-- // ...ここではエラーはありません alert('End of try runs'); // (2) <-- } catch(err) { alert('Catch is ignored, because there are no errors'); // (3) }</code></pre> </div> </div> </div></li> <li> <p>エラーの例: <code>(1)</code> と <code>(3)</code> を表示します:</p> <div id="ipbji3v5zb" data-trusted="1" class="code-example" data-highlight="[{"start":10,"cols":[{"start":34,"end":41}]},{"start":4,"end":4},{"start":2,"cols":[{"start":34,"end":41}]}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { alert('Start of try runs'); // (1) <-- lalala; // エラー, 変数は宣言されていません! alert('End of try (never reached)'); // (2) } catch(err) { alert(`Error has occured!`); // (3) <-- }</code></pre> </div> </div> </div></li> </ul> <div class="important important_warn"> <div class="important__header"><span class="important__type"><code>try..catch</code> は実行時エラーにのみ作用します</span></div> <div class="important__content"><p><code>try..catch</code> を動作させるために、コードは実行可能でなければなりません。つまり、有効なJavaScriptである必要があります。</p> <p>もしコードが構文的に誤っている場合には動作しません。例えば次は角括弧の不一致です:</p> <div id="rechnwe40h" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { {{{{{{{{{{{{ } catch(e) { alert("The engine can't understand this code, it's invalid"); }</code></pre> </div> </div> </div><p>JavaScriptエンジンは最初にコードを読み、次にそれを実行します。読み込みのフェーズで発生したエラーは “解析時間(parse-time)” エラーと呼ばれ、回復不能です(コードの内部からは)。なぜなら、エンジンはそのコードを理解することができないからです。</p> <p>そのため、<code>try..catch</code> は有効なコードの中で起きたエラーのみを扱うことができます。このようなエラーは “ランタイムエラー” または “例外” と呼ばれます。</p> </div></div> <div class="important important_warn"> <div class="important__header"><span class="important__type"><code>try..catch</code> は同期的に動作します</span></div> <div class="important__content"><p>もし <code>setTimeout</code> の中のような “スケジュールされた” コードで例外が発生した場合、<code>try..catch</code> はそれをキャッチしません。:</p> <div id="o15jt07qea" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { setTimeout(function() { noSuchVariable; // スクリプトはここで死にます }, 1000); } catch (e) { alert( "won't work" ); }</code></pre> </div> </div> </div><p><code>try..catch</code> は実際には関数をスケジュールする <code>setTimeout</code> 呼び出しをラップするためです。しかし関数自身は後で実行され、その時エンジンはすでに <code>try..catch</code> 構造を抜けています。</p> <p>スケジュールされた関数の内側の例外をキャッチするためには、その関数の中に <code>try..catch</code> が必要です。:</p> <div id="1tk6pl2pa9" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>setTimeout(function() { try { noSuchVariable; // try..catch がエラーをハンドリングします! } catch (e) { alert( "error is caught here!" ); } }, 1000);</code></pre> </div> </div> </div></div></div> <h2><a class="main__anchor" name="ref-1219" href="#ref-1219">エラーオブジェクト</a></h2><p>エラーが発生したとき、JavaScript はその詳細を含めたオブジェクトを生成します。そして <code>catch</code> の引数として渡されます。:</p> <div id="h0urlnaq7u" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { // ... } catch(err) { // <-- "エラーオブジェクト", err の代わりに別の名前を使うこともできます // ... }</code></pre> </div> </div> </div><p>すべての組み込みのエラーに対して、<code>catch</code> ブロック内のエラーオブジェクトは2つの主なプロパティを持っています。:</p> <dl> <dt><code>name</code></dt> <dd>エラー名です。未定義変数の場合、それは <code>"ReferenceError"</code> です。</dd> <dt><code>message</code></dt> <dd>エラー詳細に関するテキストメッセージです。</dd> </dl> <p>ほとんどの環境では、その他非標準のプロパティが利用可能です。最も広く使われ、サポートされているのは以下です:</p> <dl> <dt><code>stack</code></dt> <dd>現在のコールスタックです: エラーに繋がったネスト呼び出しのシーケンスに関する情報を持つ文字列です。デバッグ目的で使われます。</dd> </dl> <p>例:</p> <div id="7e62x1g2jn" data-trusted="0" class="code-example" data-highlight="[{"start":1,"end":1}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { lalala; // エラー, 変数が宣言されていません! } catch(err) { alert(err.name); // ReferenceError alert(err.message); // lalala is not defined alert(err.stack); // ReferenceError: lalala is not defined at (...スタック呼び出し) // 全体としてエラーを表示する事もできます // エラーは "name: message" として文字列に変換されます alert(err); // ReferenceError: lalala is not defined }</code></pre> </div> </div> </div><h2><a class="main__anchor" name="ref-1220" href="#ref-1220">任意の “catch” バインディング</a></h2><div class="important important_warn"> <div class="important__header"><span class="important__type">A recent addition</span></div> <div class="important__content"> This is a recent addition to the language. Old browsers may need polyfills. </div></div> <p>エラーの詳細が必要ない場合、<code>catch</code> はそれを省略できます:</p> <div id="oaizap569c" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { // ... } catch { // <-- (err) なし // ... }</code></pre> </div> </div> </div><h2><a class="main__anchor" name="ref-1221" href="#ref-1221">“try…catch” の利用</a></h2><p><code>try..catch</code> の実際のユースケースについて探索してみましょう。</p> <p>既にご存知の通り、JavaScriptは JSONエンコードされた値を読むためのメソッド <a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">JSON.parse(str)</a> がサポートされています。</p> <p>通常、それはネットワーク経由でサーバまたは別のソースから受信したデータをデコードするために使われます。</p> <p>今、次のようにデータを受信し、<code>JSON.parse</code> を呼び出します。:</p> <div id="2yw15jrad8" data-trusted="1" class="code-example" data-highlight="[{"start":2,"end":2}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let json = '{"name":"John", "age": 30}'; // サーバからのデータ let user = JSON.parse(json); // テキスト表現をJSオブジェクトに変換 // 今、 user 文字列からプロパティを持つオブジェクトです alert( user.name ); // John alert( user.age ); // 30</code></pre> </div> </div> </div><p>JSON に関する詳細な情報は、チャプター <a href="/json">JSON メソッド, toJSON</a> を参照してください。</p> <p><strong><code>json</code> が不正な形式の場合、<code>JSON.parse</code> はエラーになるのでスクリプトは “死にます”。</strong></p> <p>それで満足しますか?もちろん満足しません!</p> <p>この方法だと、もしデータが何か間違っている場合、訪問者はそれを知ることができません(開発者コンソールを開かない限り)。また、人々は、エラーメッセージなしで何かが “単に死んでいる” ことを本当に本当に嫌います。</p> <p>エラーを扱うために <code>try..catch</code> を使いましょう。:</p> <div id="1cuujwqvmj" data-trusted="1" class="code-example" data-highlight="[{"start":8,"end":11},{"start":4,"end":4}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let json = "{ bad json }"; try { let user = JSON.parse(json); // <-- エラーが起きたとき... alert( user.name ); // 動作しません } catch (e) { // ...実行はここに飛びます alert( "Our apologies, the data has errors, we'll try to request it one more time." ); alert( e.name ); alert( e.message ); }</code></pre> </div> </div> </div><p>ここでは、メッセージを表示するためのだけに <code>catch</code> ブロックを使っていますが、より多くのことをすることができます。: 新たなネットワーク要求、訪問者への代替手段の提案、ロギング機構へエラーに関する情報の送信… すべて、単に死ぬよりははるかに良いです。</p> <h2><a class="main__anchor" name="ref-1222" href="#ref-1222">独自のエラーをスローする</a></h2><p>仮に <code>json</code> が構文的に正しいが、必須の <code>"name"</code> プロパティを持っていない場合どうなるでしょう?</p> <p>このように:</p> <div id="a11jm9kb72" data-trusted="1" class="code-example" data-highlight="[{"start":5,"end":5}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let json = '{ "age": 30 }'; // 不完全なデータ try { let user = JSON.parse(json); // <-- エラーなし alert( user.name ); // name はありません! } catch (e) { alert( "doesn't execute" ); }</code></pre> </div> </div> </div><p>ここで、<code>JSON.parse</code> は通常どおり実行しますが、<code>"name"</code> の欠落は実際には我々にとってはエラーです。</p> <p>エラー処理を統一するために、<code>throw</code> 演算子を使います。</p> <h3><a class="main__anchor" name="ref-1223" href="#ref-1223">“Throw” 演算子</a></h3><p><code>throw</code> 演算子はエラーを生成します。</p> <p>構文は次の通りです:</p> <div id="qjfpksurgj" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>throw <error object></code></pre> </div> </div> </div><p>技術的には、エラーオブジェクトとしてなんでも使うことができます。たとえ、数値や文字列のようなプリミティブでもOKです。しかし、<code>name</code> と <code>message</code> プロパティを持つオブジェクトを使うのがベターです(組み込みのエラーと互換性をいくらか保つために)。</p> <p>JavaScriptは標準エラーのための多くの組み込みのコンストラクタを持っています: <code>Error</code>, <code>SyntaxError</code>, <code>ReferenceError</code>, <code>TypeError</code> などです。我々もエラーオブジェクトを作るのにそれらが使えます。</p> <p>構文は次の通りです:</p> <div id="zcd6nk6ahb" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let error = new Error(message); // or let error = new SyntaxError(message); let error = new ReferenceError(message); // ...</code></pre> </div> </div> </div><p>組み込みのエラー(任意のオブジェクトではなく、エラーのみ)では、<code>name</code> プロパティはコンストラクタの名前と全く同じになります。そして <code>message</code> は引数から取られます。</p> <p>例:</p> <div id="gky8masof5" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let error = new Error("Things happen o_O"); alert(error.name); // Error alert(error.message); // Things happen o_O</code></pre> </div> </div> </div><p><code>JSON.parse</code> が生成するエラーの種類を見てみましょう:</p> <div id="llnic2xpwd" data-trusted="1" class="code-example" data-highlight="[{"start":3,"end":3}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { JSON.parse("{ bad json o_O }"); } catch(e) { alert(e.name); // SyntaxError alert(e.message); // Unexpected token o in JSON at position 0 }</code></pre> </div> </div> </div><p>ご覧の通り、それは <code>SyntaxError</code> です。</p> <p>…そして、我々のケースでは、ユーザは必ず <code>"name"</code> を持っていると仮定するので、<code>name</code> の欠落もまた構文エラーとして扱います。</p> <p>なので、それをスローするようにしましょう:</p> <div id="1fdj2sdnym" data-trusted="1" class="code-example" data-highlight="[{"start":7,"end":7}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let json = '{ "age": 30 }'; // 不完全なデータ try { let user = JSON.parse(json); // <-- エラーなし if (!user.name) { throw new SyntaxError("Incomplete data: no name"); // (*) } alert( user.name ); } catch(e) { alert( "JSON Error: " + e.message ); // JSON Error: Incomplete data: no name }</code></pre> </div> </div> </div><p>行 <code>(*)</code> で、<code>throw</code> 演算子が与えられた <code>message</code> で <code>SyntaxError</code> を生成します。それは JavaScript が生成するのと同じ方法です。<code>try</code> の実行はすぐに停止し、制御フローは <code>catch</code> に移ります。</p> <p>今や、<code>catch</code> は<code>JSON.parse</code> と他のケースすべてのエラーハンドリングのための1つの場所になりました。</p> <h2><a class="main__anchor" name="ref-1224" href="#ref-1224">再スロー</a></h2><p>上の例で、私たちは不正なデータを処理するために <code>try..catch</code> を使っています。しかし、<code>try {...}</code> ブロックの中で <em>別の予期しないエラー</em> が発生する可能性はあるでしょうか? 変数が未定義、またはその他、単に “不正なデータ” ではない何か。</p> <p>例:</p> <div id="5z1mvsk23w" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let json = '{ "age": 30 }'; // 不完全なデータ try { user = JSON.parse(json); // <-- user の前に "let" をつけ忘れた // ... } catch(err) { alert("JSON Error: " + err); // JSON Error: ReferenceError: user is not defined // (実際にはJSONのエラーではありません) }</code></pre> </div> </div> </div><p>もちろん、すべての可能性があります! プログラマはミスをするものです。何十年も何百万人もの人が使っているオープンソースのユーティリティであっても、突然酷いバグが発見され、ひどいハッキングにつながることがあります( <code>ssh</code> ツールで起こったようなものです)。</p> <p>私たちのケースでは、<code>try..catch</code> は “不正なデータ” エラーをキャッチすることを意図しています。しかし、その性質上、<code>catch</code> は <code>try</code> からの <em>すべての</em> エラーを取得します。ここでは予期しないエラーが発生しますが、同じ <code>"JSON Error"</code> メッセージが表示されます。これは誤りでコードのデバッグをより難しくします。</p> <p>このような問題を避けるため、“再スロー” という手法が利用できます。ルールはシンプルです:</p> <p><strong>キャッチはそれが知っているエラーだけを処理し、すべてのオブジェクトを “再スロー” するべきです</strong></p> <p>“再スロー” テクニックの詳細は次のように説明できます:</p> <ol> <li>すべてのエラーをキャッチします。</li> <li><code>catch(err) {...}</code> ブロックで、エラーオブジェクト <code>err</code> を解析します。</li> <li>どう処理すればいいか分からなければ、<code>throw err</code> をします。</li> </ol> <p>通常は、<code>instanceof</code> 演算子を使用してエラーの種類がチェックできます。:</p> <div id="4ht5kl1qkj" data-trusted="1" class="code-example" data-highlight="[{"start":3,"end":3}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { user = { /*...*/ }; } catch (err) { if (err instanceof ReferenceError) { alert('ReferenceError'); // 未定義変数へのアクセスに対する "ReferenceError" } }</code></pre> </div> </div> </div><p>また、<code>erro.name</code> プロパティから、エラークラス名を取得することも可能です。すべてのネイティブエラーはエラークラス名があります。もう1つの選択肢は、<code>err.constructor.name</code> を参照することです。</p> <p>下のコードでは、<code>catch</code> が <code>SyntaxError</code> だけを処理するよう再スローを使っています。:</p> <div id="ipei2inx8z" data-trusted="1" class="code-example" data-highlight="[{"start":15,"end":19},{"start":9,"end":9}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let json = '{ "age": 30 }'; // 不完全なデータ try { let user = JSON.parse(json); if (!user.name) { throw new SyntaxError("Incomplete data: no name"); } blabla(); // 予期しないエラー alert( user.name ); } catch(e) { if (e.name == "SyntaxError") { alert( "JSON Error: " + e.message ); } else { throw e; // 再スロー (*) } }</code></pre> </div> </div> </div><p>行 <code>(*)</code> での、<code>catch</code> ブロック内部からのエラーのスローは <code>try..catch</code> を “抜けて” 外部の <code>try..catch</code> 構造(存在する場合)でキャッチされる、またはスクリプトをキルします。</p> <p>従って、<code>catch</code> ブロックは実際に扱い方を知っているエラーだけを処理しその他すべてを “スキップ” します。</p> <p>下の例は、このようなエラーが1つ上のレベルの <code>try..catch</code> で捕捉されるデモです:</p> <div id="94cbbfapis" data-trusted="1" class="code-example" data-highlight="[{"start":17,"end":17},{"start":9,"end":9},{"start":5,"end":5}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function readData() { let json = '{ "age": 30 }'; try { // ... blabla(); // error! } catch (e) { // ... if (e.name != 'SyntaxError') { throw e; // 再スロー (今のエラーの扱い方を知らない) } } } try { readData(); } catch (e) { alert( "External catch got: " + e ); // caught it! }</code></pre> </div> </div> </div><p>ここでは、<code>readData</code> は <code>SyntaxError</code> の処理の仕方だけ知っており、外部の <code>try..catch</code> はすべての処理の方法を知っています。</p> <h2><a class="main__anchor" name="ref-1225" href="#ref-1225">try…catch…finally</a></h2><p>待ってください、それですべてではありません。</p> <p><code>try..catch</code> 構造はもう1つのコード句: <code>finally</code> を持つ場合があります。</p> <p>もし存在する場合、それはすべてのケースで実行します。:</p> <ul> <li>エラーが無かった場合は、<code>try</code> の後で。</li> <li>エラーがあった場合には <code>catch</code> の後で。</li> </ul> <p>拡張された構文はこのようになります。:</p> <div id="8i0upvaul9" data-trusted="1" class="code-example" data-highlight="[{"start":4,"cols":[{"start":2,"end":9}]},{"start":2,"cols":[{"start":2,"end":7}]},{"start":0,"cols":[{"start":0,"end":3}]}]"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { ... コードを実行しようとします ... } catch(e) { ... エラーを処理します ... } finally { ... 常に実行します ... }</code></pre> </div> </div> </div><p>このコードを実行してみましょう。:</p> <div id="fq1zmu0zrm" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { alert( 'try' ); if (confirm('Make an error?')) BAD_CODE(); } catch (e) { alert( 'catch' ); } finally { alert( 'finally' ); }</code></pre> </div> </div> </div><p>このコードは2つの実行方法があります。:</p> <ol> <li>もし “Make an error” に “Yes” と答えると、<code>try -> catch -> finally</code> となります。</li> <li>もし “No” と言えば、<code>try -> finally</code> となります。</li> </ol> <p><code>finally</code> 句は <code>try..catch</code> の前に何かを開始して、どのような結果であれファイナライズをしたいときに頻繁に使われます。</p> <p>例えば、フィボナッチ数関数 <code>fib(n)</code> にかかる時間を計測したいとします。当然ながら、それを実行する前に計測を開始して、実行後に終了させることができます。しかし、仮に関数呼び出しの間でエラーが起きたらどうなるでしょう?特に下のコードの <code>fib(n)</code> の実装では、負の値または非整数値だとエラーを返します。</p> <p><code>finally</code> 句は何があっても計測を完了させるのに良い場所です。</p> <p>ここで、<code>finally</code> は両方のシチュエーション – <code>fib</code> の実行が成功するケースと失敗するケース – で時間が正しく計測されることを保証します。:</p> <div id="x023k9tr33" data-trusted="1" class="code-example" data-highlight="[{"start":17,"end":19}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>let num = +prompt("Enter a positive integer number?", 35) let diff, result; function fib(n) { if (n < 0 || Math.trunc(n) != n) { throw new Error("Must not be negative, and also an integer."); } return n <= 1 ? n : fib(n - 1) + fib(n - 2); } let start = Date.now(); try { result = fib(num); } catch (e) { result = 0; } finally { diff = Date.now() - start; } alert(result || "error occured"); alert( `execution took ${diff}ms` );</code></pre> </div> </div> </div><p>コードを実行して <code>prompt</code> に <code>35</code> を入力することで確認できます – 通常 <code>try</code> の後に <code>finally</code> を実行します。そして <code>-1</code> を入れると – すぐにエラーになり、その実行は <code>0ms</code> となります。両方の計測は正しく行われています。</p> <p>つまり、関数を終了するには方法が2つあります: <code>return</code> または <code>throw</code> です。 <code>finally</code> 句はそれら両方とも処理します。</p> <div class="important important_smart"> <div class="important__header"><span class="important__type">変数は <code>try..catch..finally</code> の内部でローカルです</span></div> <div class="important__content"><p>上のコードで <code>result</code> と <code>diff</code> 変数は <code>try..catch</code> の <em>前</em> で宣言されていることに注意してください。</p> <p>そうでなく、<code>let</code> が <code>{...}</code> ブロックの中で作られている場合、その中でしか見えません。</p> </div></div> <div class="important important_smart"> <div class="important__header"><span class="important__type"><code>finally</code> と <code>return</code></span></div> <div class="important__content"><p>Finally 句は <code>try..catch</code> からの <em>任意の</em> 終了に対して機能します。それは明白な <code>return</code> も含みます。</p> <p>下の例では、<code>try</code> の中で <code>return</code> があります。この場合、<code>finally</code> は制御が外部コードに戻る前に実行されます。</p> <div id="0zozh62a13" data-trusted="1" class="code-example" data-highlight="[{"start":8,"end":8},{"start":3,"end":3}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function func() { try { return 1; } catch (e) { /* ... */ } finally { alert( 'finally' ); } } alert( func() ); // 最初に finally の alert が動作し、次にこれが動作します</code></pre> </div> </div> </div></div></div> <div class="important important_smart"> <div class="important__header"><span class="important__type"><code>try..finally</code></span></div> <div class="important__content"><p><code>catch</code> 句がない <code>try..catch</code> 構造も役立ちます。私たちはここでエラーを正しく処理したくないが、開始した処理が完了したことを確認したいときに使います。</p> <div id="0lwo072neu" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function func() { // (計測など)完了させる必要のあるなにかを開始する try { // ... } finally { // すべてが死んでいても完了させる } }</code></pre> </div> </div> </div><p>上のコードでは、<code>try</code> の内側のエラーは常に抜けます。なぜなら <code>catch</code> がないからです。しかし <code>finally</code> は実行フローが外部に移る前に機能します。</p> </div></div> <h2><a class="main__anchor" name="ref-1226" href="#ref-1226">グローバルな catch</a></h2><div class="important important_warn"> <div class="important__header"><span class="important__type">環境特有</span></div> <div class="important__content"><p>このセクションの情報はコアなJavaScriptの一部ではありません。</p> </div></div> <p><code>try..catch</code> の外側で致命的なエラーが起きてスクリプトが死んだことをイメージしてください。プログラミングエラーやその他何か酷いものによって。</p> <p>そのような出来事に反応する方法はありますか? エラーをログに記録したり、ユーザーに何かを見せたり(通常はエラーメッセージが表示されません)。</p> <p>仕様ではそのようなものはありませんが、通常、環境がそれを提供しています。なぜなら本当に有用だからです。例えば、Node.js はそのために <a href="https://nodejs.org/api/process.html#process_event_uncaughtexception">process.on(‘uncaughtException’)</a>を持っています。また、ブラウザでは関数を特別な <a href="https://developer.mozilla.org/ja/docs/Web/API/GlobalEventHandlers/onerror">window.onerror</a> プロパティに代入することができます。それはキャッチしていないエラーの場合に実行されます。</p> <p>構文:</p> <div id="n0ylfw6v3i" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>window.onerror = function(message, url, line, col, error) { // ... };</code></pre> </div> </div> </div><dl> <dt><code>message</code></dt> <dd>エラーメッセージ</dd> <dt><code>url</code></dt> <dd>エラーが起きたスクリプトのURL</dd> <dt><code>line</code>, <code>col</code></dt> <dd>エラーが起きた行と列番号</dd> <dt><code>error</code></dt> <dd>エラーオブジェクト</dd> </dl> <p>例:</p> <div id="9dositb863" data-trusted="0" class="code-example" data-demo-height="1" data-refresh="1" data-highlight="[{"start":1,"end":3}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="表示" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-markup"><code><script> window.onerror = function(message, url, line, col, error) { alert(`${message}\n At ${line}:${col} of ${url}`); }; function readData() { badFunc(); // おっと、何かがおかしいです! } readData(); </script></code></pre> </div> </div> </div><p>グローバルハンドラー <code>window.onerror</code> の役割は、通常スクリプトの実行の回復ではありません – プログラミングエラーの場合、恐らくそれは不可能なので開発者にエラーメッセージを送ります。</p> <p>このようなケースでエラーログを提供する web サービスもあります。https://errorception.com> や <a href="http://www.muscula.com">http://www.muscula.com</a>。</p> <p>それらは次のように動きます:</p> <ol> <li>私たちはサービスに登録し、ページに挿入するためのJSのピース(またはスクリプトのURL)をそれらから得ます。</li> <li>そのJSスクリプトはカスタムの <code>window.onerror</code> 関数を持っています。</li> <li>エラーが起きた時、そのサービスへネットワークリクエストを送ります。</li> <li>私たちはサービスのWebインタフェースにログインしてエラーを見ることができます。</li> </ol> <h2><a class="main__anchor" name="ref-1227" href="#ref-1227">サマリ</a></h2><p><code>try..catch</code> 構造はランタイムエラーを処理することができます。文字通りコードを実行しようと試みて、その中で起こるエラーをキャッチします。</p> <p>構文は次の通りです:</p> <div id="g6f3ujdv1o" data-trusted="1" class="code-example"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { // コードを実行 } catch(err) { // エラーが起きた場合、ここにジャンプ // err はエラーオブジェクト } finally { // すべてのケースで try/catch 後に実行する }</code></pre> </div> </div> </div><p><code>catch</code> セクションがない、または <code>finally</code> がない場合があります。なので <code>try..catch</code> と <code>try..finally</code> もまた有効です。</p> <p>エラーオブジェクトは次のプロパティを持っています。:</p> <ul> <li><code>message</code> – 人が読めるエラーメッセージです。</li> <li><code>name</code> – エラー名を指す文字列です(エラーコンストラクタ名)</li> <li><code>stack</code> (非標準) – エラー生成時のスタックです。</li> </ul> <p>エラーオブジェクトが不要であれば、<code>catch (err) {</code> の代わりに <code>catch {</code> とすることで省略できます。</p> <p>また、<code>throw</code> 演算子を使って独自のエラーを生成することもできます。技術的には、<code>throw</code> の引数は何でもよいですが、通常は組み込みの <code>Error</code> クラスを継承しているエラーオブジェクトです。次のチャプターでエラーを拡張する方法について詳しく説明します。</p> <p><em>再スロー</em> はエラーハンドリングの非常に重要なパターンです。: <code>catch</code> ブロックは通常、特定のエラータイプを処理する方法を予期し、知っています。したがって、知らないエラーは再スローすべきです。</p> <p>たとえ <code>try..catch</code> を持っていない場合でも、ほとんどの環境では “抜け出た” エラーをキャッチするために “グローバル” なエラーハンドラを設定することができます。ブラウザでは、それは <code>window.onerror</code> です。</p> </div></article><div class="tasks formatted"><h2 class="tasks__title" id="tasks"><a class="tasks__title-anchor main__anchor main__anchor main__anchor_noicon" href="#tasks">タスク</a></h2><div class="task tasks__task"><div class="task__header"><div class="task__title-wrap"><h3 class="task__title"><a class="main__anchor" href="#ref-1228" name="ref-1228">Finally or just the code?</a></h3><a class="task__open-link" href="/task/finally-or-code-after" target="_blank"></a></div><div class="task__header-note"><span class="task__importance" title="タスクの重要度を表し、1 から 5 までです">重要性: 5</span></div><div class="task__content"><div class="task__formatted"><p>2つのコードの断片を比較してみてください。</p> <ol> <li> <p>1つ目は <code>try..catch</code> のあとにコードを実行するために <code>finally</code> を使います:</p> <div id="d0g0mhg9lr" data-trusted="1" class="code-example" data-highlight="[{"start":5,"end":5}]"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { work work } catch (e) { handle errors } finally { 作業場所のクリーンアップ }</code></pre> </div> </div> </div></li> <li> <p>2つ目は <code>try..catch</code> の直後にクリーンアップする処理を置きます:</p> <div id="6foonvnvlu" data-trusted="1" class="code-example" data-highlight="[{"start":6,"end":6}]"> <div class="codebox code-example__codebox"> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>try { work work } catch (e) { handle errors } 作業場所のクリーンアップ</code></pre> </div> </div> </div></li> </ol> <p>私たちは、処理が開始された後には、それがエラーかどうかは関係なく必ずクリーンアップが必要です。</p> <p><code>finally</code> を使うことの利点はあるでしょうか?それとも両方のコードは同じでしょうか?もし利点がある場合はそれが関係する例を挙げてください。</p> </div><button class="task__solution" type="button">解答</button><div class="task__answer"><div class="task__answer-content"><div class="formatted"><p>その違いは、関数内のコードを見ると明らかになります。</p> <p>もし <code>try..catch</code> の “飛び出し” がある場合、振る舞いは異なります。</p> <p>例えば、<code>try..catch</code> の中で <code>return</code> がある場合です。<code>finally</code> 句は <code>try..catch</code> が <em>どのような終わり方の場合にでも</em> 動作します。たとえ、<code>return</code> 文経由でさえも。</p> <div id="liuo7d7xe3" data-trusted="1" class="code-example" data-highlight="[{"start":3,"end":3}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function f() { try { alert('start'); return "result"; } catch (e) { /// ... } finally { alert('cleanup!'); } } f(); // cleanup!</code></pre> </div> </div> </div><p>…もしくは次のように <code>throw</code> がある場合:</p> <div id="13h9g4twuc" data-trusted="1" class="code-example" data-highlight="[{"start":7,"end":7}]"> <div class="codebox code-example__codebox"> <div class="toolbar codebox__toolbar"> <div class="toolbar__tool"> <a href="#" title="実行" data-action="run" class="toolbar__button toolbar__button_run"></a> </div> <div class="toolbar__tool"> <a href="#" title="サンドボックで開く" target="_blank" data-action="edit" class="toolbar__button toolbar__button_edit"></a> </div> </div> <div class="codebox__code" data-code="1"> <pre class="line-numbers language-javascript"><code>function f() { try { alert('start'); throw new Error("an error"); } catch (e) { // ... if("can't handle the error") { throw e; } } finally { alert('cleanup!') } } f(); // cleanup!</code></pre> </div> </div> </div><p>ここで <code>finally</code> はクリーンアップを保証します。もし <code>f</code> の終わりにコードをおいた場合は実行されない場合があります。</p> </div></div><button class="close-button task__answer-close" type="button" title="閉じる"></button></div></div></div></div></div></div><div class="page__nav-wrap"><a class="page__nav page__nav_prev" href="/error-handling" data-tooltip="エラーハンドリング"><span class="page__nav-text"><span class="page__nav-text-shortcut"></span></span><span class="page__nav-text-alternate">前のレッスン</span></a><a class="page__nav page__nav_next" href="/custom-errors" data-tooltip="カスタムエラー, Error の拡張"><span class="page__nav-text"><span class="page__nav-text-shortcut"></span></span><span class="page__nav-text-alternate">次のレッスン</span></a></div><div class="article-tablet-foot tablet-only"><div class="article-tablet-foot__layout"><div class="share-icons"><span class="share-icons__title">シェア</span><a class="share share_tw" href="https://twitter.com/share?url=https%3A%2F%2Fja.javascript.info%2Ftry-catch" rel="nofollow"></a><a class="share share_fb" href="https://www.facebook.com/sharer/sharer.php?s=100&p%5Burl%5D=https%3A%2F%2Fja.javascript.info%2Ftry-catch" rel="nofollow"></a></div><div class="article-tablet-foot__map"><a class="map" href="/tutorial/map" data-action="tutorial-map"><span class="map__text">チュートリアルマップ</span></a></div></div></div><div class="comments formatted" id="comments"><div class="comments__header"><h2 class="comments__header-title"><a href="#comments" name="comments">コメント</a></h2><div class="comments__read-before"><span class="comments__read-before-link">コメントをする前に読んでください…</span><div class="comments__read-before-popup"><div class="comments__read-before-popup-i"><ul><li>自由に記事への追加や質問を投稿をしたり、それらに回答してください。</li><li>数語のコードを挿入するには、<code><code></code> タグを使ってください。複数行の場合は <code><pre></code> を、10行を超える場合にはサンドボックスを使ってください(<a href='https://plnkr.co/edit/?p=preview'>plnkr</a>, <a href='https://jsbin.com'>JSBin</a>, <a href='http://codepen.io'>codepen</a>…)。</li><li>記事の中で理解できないことがあれば、詳しく説明してください。</li></ul></div></div></div></div><div id="disqus_thread"></div><script>var disqus_config = function() { if (!this.page) this.page = {}; Object.assign(this.page, {"url":"https:\/\/ja.javascript.info\/try-catch","identifier":"\/try-catch"}); };</script><script>var disqus_shortname = "ja-javascript-info";</script><script>var disqus_enabled = true;</script></div></script></main></div><div class="sidebar page__sidebar sidebar sidebar_sticky-footer"><button class="sidebar__toggle" data-sidebar-toggle></button><a class="map" href="/tutorial/map" data-action="tutorial-map" data-tooltip="チュートリアルマップ"></a><div class="sidebar__inner"><div class="sidebar__content"><div class="sidebar__section"><h4 class="sidebar__section-title">チャプター</h4><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="/error-handling">エラーハンドリング</a></li></ul></nav></div><div class="sidebar__section"><h4 class="sidebar__section-title">レッスンナビゲーション</h4><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1218">“try…catch” 構文</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1219">エラーオブジェクト</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1220">任意の “catch” バインディング</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1221">“try…catch” の利用</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1222">独自のエラーをスローする</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1224">再スロー</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1225">try…catch…finally</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1226">グローバルな catch</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#ref-1227">サマリ</a></li></ul></nav></div><div class="sidebar__section"><nav class="sidebar__navigation"><ul class="sidebar__navigation-links"><li class="sidebar__navigation-link"><a class="sidebar__link" href="#tasks">タスク (1)</a></li><li class="sidebar__navigation-link"><a class="sidebar__link" href="#comments">コメント</a></li></ul></nav></div><div class="sidebar__section"><div class="sidebar__section-title">シェア</div><a class="share share_tw sidebar__share" href="https://twitter.com/share?url=https%3A%2F%2Fja.javascript.info%2Ftry-catch" rel="nofollow"></a><a class="share share_fb sidebar__share" href="https://www.facebook.com/sharer/sharer.php?s=100&p[url]=https%3A%2F%2Fja.javascript.info%2Ftry-catch" rel="nofollow"></a></div><div class="sidebar__section"><a class="sidebar__link" href="https://github.com/javascript-tutorial/ja.javascript.info/blob/master/1-js/10-error-handling/1-try-catch" rel="nofollow">GitHubで編集</a></div></div></div></div></div></div><div class="page-footer"><ul class="page-footer__list"><li class="page-footer__item page-footer__item_copy">© 2007—2025 Ilya Kantor</li><li class="page-footer__item page-footer__item_about"><a class="page-footer__link" href="/about">プロジェクトについて</a></li><li class="page-footer__item page-footer__item_contact"><a class="page-footer__link" href="/about#contact-us">コンタクト</a></li></ul></div></body></html>