try...catch

The try...catch statement marks a block of statements to try, and specifies a response, should an exception be thrown.

문법

try {
   try_statements
}
[catch (exception_var_1 if condition_1) { // 비표준
   catch_statements_1
}]
...
[catch (exception_var_2) {
   catch_statements_2
}]
[finally {
   finally_statements
}]
try_statements
실행될 선언들
catch_statements_1, catch_statements_2
try 블록에서 예외가 발생했을 때 실행될 선언들
exception_var_1, exception_var_2
catch 항목과 관련된 예외 객체를 담기 위한 식별자
condition_1
조건식
finally_statements
try 선언이 완료된 이후에 실행된 선언들. 이 선언들은 예외 발생 여부와 상관없이 실행된다.

설명

try 선언의 구성은 하나 혹은 그 이상의 선언을 포함한 try 블록 및 catch 항목이나 finally 항목 중 최소한 하나 혹은 둘 다 포함하여 이루어진다. 즉, try 선언에는 세 가지 형식이 존재한다.

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

catch절은 try 블록 안에서 예외가 throw 되었을 때 무엇을 할지를 명시하는 기술(記述)을 포함합니다.  즉, 여러분은 try 블록이 성공하기를 원하고, 만약 성공하지 못했을 때 catch블록으로 제어를 넘기길 원할 것입니다. try 블록 (또는 try 블록 내에서 호출된 함수) 내의 명령문이 예외를 throw 하면 제어가 catch 절로 즉시 이동합니다. try 블록에 예외가 발생하지 않으면 catch 절을 건너뜁니다.

finally 절은 try 블록과 catch 절 다음으로 실행됩니다. 예외사항의 throw 혹은 catch 여부에 관계없이 항상 실행됩니다.

하나 이상의 try 문을 중첩 할 수 있습니다. 내부의 try 문에 catch 문이 없으면, 둘러싼 try 문의 catch 절이 입력됩니다.

또한 try 문을 사용하여 예외처리를 합니다. 예외처리에 대해 더 알고 싶다면, JavaScript Guide 를 참고하세요.

무조건적 catch

무조건적 catch 문이 하나만 사용될경우, catch 블럭은 예외사항이 throw 되었을때 항상 들어가집니다. 예를들어, 다음의 코드에 예외사항이 발생할때, 제어가 catch 문으로 이동하게 됩니다.

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

조건적 catch

Non-standard
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

또한 특정 예외사항에 대한 한개 또는 한개 이상의 조건적 catch 문을 사용할 수 있습니다. 이 경우에, 특정 예외사항에 따라 적절한 catch 문으로 이동하게 됩니다. 다음 예제에서, try 문 안의 코드는 세가지 예외사항: TypeError, RangeError,EvalError을 throw 할 수 있습니다.. 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.

Reminder: this functionality is not part of the ECMAScript specification.

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
}

And here is how to do implement the same "Conditional catch clauses" using only simple JavaScript conforming to the 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.

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.

The finally clause

The finally clause contains statements to execute after the try block and catch clause(s) execute, but before the statements following the try statement. The finally clause executes regardless of whether or not an exception is thrown. If an exception is thrown, the statements in the finally clause execute even if no catch clause handles the exception.

You can use the finally clause to make your script fail gracefully when an exception occurs; for example, you may need to release a resource that your script has tied up. 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
}

Examples

Nested try-blocks

First let's see what happens with this:

try {
  try {
    throw new Error("oops");
  }
  finally {
    console.log("finally");
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

// Output:
// "finally"
// "outer" "oops"

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

try {
  try {
    throw new Error("oops");
  }
  catch (ex) {
    console.error("inner", ex.message);
  }
  finally {
    console.log("finally");
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

// Output:
// "inner" "oops"
// "finally"

And now, lets re-throw the error.

try {
  try {
    throw new Error("oops");
  }
  catch (ex) {
    console.error("inner", ex.message);
    throw ex;
  }
  finally {
    console.log("finally");
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

// Output:
// "inner" "oops"
// "finally"
// "outer" "oops"

Any given exception will be caught only once by the nearest enclosing catch-block, unless it is re-thrown. Of course, any new exceptions raised in the "inner" block (because code in catch-block may do something that throws), will be caught by the "outer" block.

Returning from a finally block

If the finally block returns a value, this value becomes the return value of the entire try-catch-finally production, regardless of any return statements in the try and catch blocks. This includes exceptions thrown inside of the catch block:

try {
  try {
    throw new Error("oops");
  }
  catch (ex) {
    console.error("inner", ex.message);
    throw ex;
  }
  finally {
    console.log("finally");
    return;
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

// Output:
// "inner" "oops"
// "finally"

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.

Specifications

Specification Status Comment
ECMAScript 3rd Edition (ECMA-262) Standard Initial definition. Implemented in JavaScript 1.4
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 Latest Draft (ECMA-262)
The definition of 'try statement' in that specification.
Draft Not part of the current ECMA-262 standard: Multiple catch clauses and conditional clauses (SpiderMonkey extension, JavaScript 1.5).

Browser compatibility

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) (Yes) (Yes) (Yes)
Conditional clauses
(non-standard)
No support (Yes) No support No support No support
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)
Conditional clauses
(non-standard)
No support No support (Yes) No support No support No support

See also