try...catch

Ez a fordítás hiányos. Segítsen a cikk angolról történő lefordításában

try...catch szerkezet utasítások futtatására, majd a keletkező kivételek érzékelésére, kezelésére való.

Megjegyzés: ebben a cikkben a kivétel szó az angol szaknyelvi exception, blokk pedig a block vagy clause szó fordítása.

Szerkezet

try {
   try_statements
}
[catch (exception_var_1 if condition_1) { // nem szabványos
   catch_statements_1
}]
...
[catch (exception_var_2) {
   catch_statements_2
}]
[finally {
   finally_statements
}]
try_statements
Azok az utasítások, amelyek kivételt válthatnak ki.
catch_statements_1, catch_statements_2
Azok az utasítások, amelyek akkor hajtódnak végre, ha valami kivételt vált ki a try blokkban.
exception_var_1, exception_var_2
Annak a változónak a neve, amelyben az utána következő catch blokkban elérhető lesz a kivételobjektum (Exception).
condition_1
Valamilyen feltétel (mint egy if() kifejezésben).
finally_statements
Azok az utasítások, amelyeket a try blokk után le kell futtatni, tehát ezek attól függetlenül végrehajtódnak, hogy a try blokkban történt-e kivétel.

Kifejtés

A try szerkezetnek 3 megjelenési formája van:

  1. try...catch
  2. try...finally
  3. try...catch...finally

A try, a catch és a finally blokk egy vagy több utasításból állhat. A kapcsos zárójelek használata kötelező, még akkor is, ha egy utasításból áll csak a blokk. A try blokk után legalább egy catch vagy finally blokknak kell lennie.:

A catch blokk tartalmazza azokat az utasításokat, amelyek akkor hajtódnak végre, ha valami kivételt vált ki a try blokkban. Ha valami kivételt vált ki, a try blokk végrehajtása azonnal megszakad, és a catch blokk hajtódik végre. Ha nem történik kivétel, a catch blokk nem hajtódik végre.

A finally blokk végrehajtása a try és a catch blokk(ok) végrehajtása után, közvetlenül a blokk utáni utasítások előtt. Mindig végrehajtódik, attól függetlenül, hogy a try blokk sikeres volt-e.

A try szerkezetek egymásba ágyazhatóak. Ha egy beágyazott try blokkhoz nem tartozik catch blokk, az azt tartalmazó try blokkhoz tartozó catch/finally fog végrehajtódni.

A try szerkezettel a JavaScript kivételeit is lehet kezelni. További információ róluk: JavaScript Guide.

Feltétel nélküli catch blokk

Egyszerű, feltétel nélküli catch blokk esetén bármilyen kivétel váltódik ki, ugyanaz a blokk fog végrehajtódni. Például

try {
   throw 'myException'; // generates an exception
}
catch (e) {
   // statements to handle any exceptions
   logMyErrors(e); // pass exception object to error handler
}

A catch blokk használata során meg kell adnunk egy változónevet, ez a változó fogja tárolni a kivételobjektumot. A catch blokkban megadott változó élettartama eltér a szokásostól: a változó a catch blokk végrehajtása előtt jön létre, és a végrehajtás után nem elérhető.

Feltételes catch blokk

You can also use one or more conditional catch clauses to handle specific exceptions. In this case, the appropriate catch clause is entered when the specified exception is thrown. In the following example, code in the try block can potentially throw three exceptions: TypeError, RangeError, and EvalError. When an exception occurs, control transfers to the appropriate catch clause. If the exception is not one of the specified exceptions and an unconditional catch clause is found, control transfers to that catch clause.

If you use an unconditional catch clause with one or more conditional catch clauses, the unconditional catch clause must be specified last. Otherwise, the unconditional catch clause will intercept all types of exception before they can reach the conditional ones.

Emlékeztető: ez a lehetőség nem az ECMAScript szabvány része.

try {
    myroutine(); // may throw three types of exceptions
} catch (e if e instanceof TypeError) {
    // statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
    // statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
    // statements to handle EvalError exceptions
} catch (e) {
    // statements to handle any unspecified exceptions
    logMyErrors(e); // pass exception object to error handler
}

Here is the same "Conditional catch clauses" using code that conforms to ECMAScript specification (obviously it's more verbose, but works everywhere):

try {
    myroutine(); // may throw three types of exceptions
} catch (e) {
    if (e instanceof TypeError) {
        // statements to handle TypeError exceptions
    } else if (e instanceof RangeError) {
        // statements to handle RangeError exceptions
    } else if (e instanceof EvalError) {
        // statements to handle EvalError exceptions
    } else {
       // statements to handle any unspecified exceptions
       logMyErrors(e); // pass exception object to error handler
    }
}

The exception identifier

When an exception is thrown in the try block, exception_var (e.g. the e in catch (e)) holds the value specified by the throw statement. You can use this identifier to get information about the exception that was thrown. As of Firefox 58, when the exception is unused, the identifier can be omitted, as in

function isValidJSON(text) {
    try {
        JSON.parse(text);
        return true;
    } catch {
        return false;
    }
}

This identifier is local to the catch clause. That is, it is created when the catch clause is entered, and after the catch clause finishes executing, the identifier is no longer available.

A finally blokk

A finally blokk azokat az utasításokat tartalmazza, amelyeket a catch blokk(ok) után, de a try-catch-finally szerkezet előtt kell végrehajtani. Mindenképpen végrehajtódik, attól függetlenül, hogy a try blokkban váltódott-e ki kivétel. A finally blokk megléte elfogadhatóvá teszi a catch blokk hiányát, de a kivételek megjelennek a blokkon kívül is. Amennyiben hiányzik a catch blokk, először a try-ban kiváltódott kivételek jelennek meg, majd ezután hajtódik végre a finally blokk.

A finally blokkot gyakran használják a program hiba esetén történő leállása előtti feladatok elvégzésére.

Enyhén szólva furcsának tűnhet, hogy a JavaScript kivételekhez kapcsolódó részében szerepel egy olyan ág is, ami attól függetlenül végrehajtódik, hogy váltódott-e ki kivétel. Ennek azomban, a látszattal ellentétben van értelme. A hangsúly nem azon van, hogy a finally blokk mindig végrehajtódik, hanem hogy az azt követő utasítások nem feltétlenül.

Például ha egy másik kivétel váltódik ki egy try-catch blokkon belül, semmilyen más kód ugyanabban a külső try-catch blokkban nem fog végrehajtódni.

For instance, if another exception occurs inside a try's catch-block, any remaining code in the same outer try-block enclosing that try..catch (or in the main flow, if not in an outer try-block) , will not get executed, since control is immediately transferred to the outer try's catch-block (or the internal error-generator, if not in a try-block).  

Thus, any routine cleanup code done in that enclosed (or the main) section before it exits, will be skipped.  However, If the try-block has a finally-block, then that finally-block code will be executed first to permit any such cleanup, and THEN the other try's catch-block (or the error-generator) will get control to handle the second exception.  

Now, if that routine cleanup must be done whether or not the try..catch code succeeds, then if the finally-block only executed after an exception, the same cleanup code would have to be duplicated both inside and outside the finally-block, and therefore there is no reason not to have just the finally-block alone, and let it execute regardless of exceptions or not.

The following example opens a file and then executes statements that use the file (server-side JavaScript allows you to access files). If an exception is thrown while the file is open, the finally clause closes the file before the script fails. The code in finally also executes upon explicitly returning from try or catch block.

openMyFile();
try {
   // tie up a resource
   writeMyFile(theData);
}
finally {
   closeMyFile(); // always close the resource
}

Példák

Beágyazott try blokkok

Először is, nézzük meg ezt:

try {
  try {
    throw new Error('hoppácska');
  }
  finally {
    console.log('finally blokk');
  }
}
catch (ex) {
  console.error('külső catch blokk', ex.message);
}

// Kimenet:
// "finally blokk"
// "külső catch blokk" "hoppácska"

Now, if we already caught the exception in the inner try-block by adding a catch block

try {
  try {
    throw new Error('hoppácska');
  }
  catch (ex) {
    console.error('belső catch blokk', ex.message);
  }
  finally {
    console.log('finally blokk');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Kimenet:
// "belső catch blokk" "hoppácska"
// "finally blokk"

Most pedig dobjuk tovább a kivételt:

try {
  try {
    throw new Error('hoppácska');
  }
  catch (ex) {
    console.error('belső catck blokk', ex.message);
    throw ex;
  }
  finally {
    console.log('finally blokk');
  }
}
catch (ex) {
  console.error('külső catck blokk', ex.message);
}

// Output:
// "belső catck blokk" "hoppácska"
// "finally blokk"
// "külső catck blokk" "hoppácska"

Minden kivételt csak a legközelebbi catch blokk fog elkapni, kivéve ha innen tovább dobjuk. Ez esetben a belső catch blokkból dobott kivételt a külső try-hez tartozó catch blokk fogja elkapni.

return használata a finally blokkban

Ha a finally blokk értéket ad vissza, ez az érték a teljes try-catch-finally szerkezet vissszatérési értékévé válik, a try és catch blokkokban lévő return utasításoktól függetlenül. Ebbe beletartoznak a catch blokkon belül dobott kivételek is.

(function() {
  try {
    try {
      throw new Error('hoppácska');
    }
    catch (ex) {
      console.error('belső catch blokk', ex.message);
      throw ex;
    }
    finally {
      console.log('finally blokk');
      return;
    }
  }
  catch (ex) {
    console.error('külső', ex.message);
  }
})();

// Kimenet:
// "belső catch blokk" "hoppácska"
// "finally blokk"

The outer "oops" is not thrown because of the return in the finally block. The same would apply to any value returned from the catch block.

Specifikációk

Specifikáció Státusz Megjegyzés
ECMAScript 3rd Edition (ECMA-262) Standard

Az első leírás. A JavaScript 1.4-ben lett megvalósítva.

ECMAScript 5.1 (ECMA-262)
The definition of 'try statement' in that specification.
Standard
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'try statement' in that specification.
Standard
ECMAScript (ECMA-262)
The definition of 'try statement' in that specification.
Living Standard Nem része a jelenleg ECMA-262 szabványnak: Több catch blokk és feltételes bokkok (SpiderMonkey kiterjesztés, JavaScript 1.5).

Browser compatibility

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
try...catchChrome Full support 1Edge Full support 12Firefox Full support 1IE Full support 5Opera Full support 4Safari Full support 1WebView Android Full support 1Chrome Android Full support 18Firefox Android Full support 4Opera Android Full support 10.1Safari iOS Full support 1Samsung Internet Android Full support 1.0nodejs Full support 0.1.100
Optional catch bindingChrome Full support 66Edge Full support 79Firefox Full support 58IE No support NoOpera Full support 53Safari Full support 11.1WebView Android Full support 66Chrome Android Full support 66Firefox Android Full support 58Opera Android Full support 47Safari iOS Full support 11.3Samsung Internet Android Full support 9.0nodejs Full support 10.0.0

Legend

Full support  
Full support
No support  
No support

See also