try...catch
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
As declaraçõestry...catch marcam um bloco de declarações para testar (try), e especifica uma resposta, caso uma exceção seja lançada.
Sintaxe
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
Declarações (statements) a serem executadas.
catch_statements_1
,catch_statements_2
Declarações que são executadas se uma exceção é lançada no bloco
try.
exception_var_1
,exception_var_2
Um indentificador que leva um objeto exceção para uma cláusula
catch
associada.condition_1
Uma expressão condicional.
finally_statements
Declarações que são executadas depois que a declaração
try
é completada. Essas declarações são executadas independetemente se uma exceção foi ou não lançada ou capturada.
Descrição
A declaraçãotry
consiste em um blocotry
, que contém uma ou mais declarações, e ao menos uma cláusulacatch
ou uma cláusulafinally
, ou ambas. Ou seja, há 3 formas de declaraçõestry
:
try...catch
try...finally
try...catch...finally
Uma cláusulacatch
contém declarações que especificam o que fazer caso uma exceção seja lançada no blocotry
. Ou seja, se você quer que o blocotry
tenha êxito, e caso não tenha, você quer que o controle passe para o blococatch
. Caso qualquer declaração dentro do blocotry
(ou em uma função chamada no interior do blocotry
) lançar uma exceção o controle imediatamente muda para a cláusulacatch
. Se nenhuma exceção for lançada no blocotry
a cláusulacatch
é ignorada.
A cláusulafinally
é executada após a excecução do blocotry
e da(s) cláusula(s)catch
porém antes das declarações seguintes aotry
. Ela sempre é executada, independente se uma exceção for lançada ou capturada.
Você pode aninhar uma ou mais declaraçõestry
. Caso uma declaraçãotry
interior não tenha uma cláusulacatch
, a cláusula catch pertencente a declaraçãotry
que a envolve é introduzida.
Você pode usar a declaração try para manipular exceções em JavaScript. Veja oGuia Javascript para informações sobre exceções em JavaScript.
Cláusula catch incondicional
Quando uma única, incondicional cláusulacatch
é utilizada, o blococatch
é inserido quando qualquer exceção for lançada. Por exemplo, quando a exceção ocorre no código a seguir, o controle é transferido para a cláusulacatch
.
try { throw "myException"; // gera uma exceção} catch (e) { // declarações para manipular quaisquer exceções logMyErrors(e); // passa o objeto de exceção para o manipulador de erro}
Cláusulascatch
condicionais
Não padrão: Este recurso não é padronizado. Não recomendamos o uso de recursos não padronizados em produção, pois eles têm suporte limitado nos navegadores e podem mudar ou ser removidos. No entanto, podem ser uma alternativa viável em casos específicos onde não exista uma opção padrão.
Você pode utilizar uma ou mais cláusulascatch
condicionals para manipular exceções específicas. Nesse caso a cláusulacatch
apropriada será inserida quando a exceção espeficica for lançada. No exemplo a seguir, o código no blocotry
pode potencialmente jogar três exceções:TypeError
,RangeError
, eEvalError
. Quando a exceção ocorre, o controle transfere para a cláusulacatch
apropriada. Caso a exceção não seja uma das especificadas e uma cláusulacatch
incondicional for encontrada, o controle é transferido para essa cláusulacatch
.
Se utilizar uma cláusulacatch
incondicional com uma ou mais cláusulascatch
condicionais, o catch incondicional deve ser especificado por último. Caso contrário, o catch incondicional interceptará todos os tipos de exceção antes que eles alcancem os condicionais.
Nota: Essa funcionalidade não é parte da especificação ECMAScript.
try { myroutine(); // pode lançar três tipos de exceções} catch (e if e instanceof TypeError) { // declarações para manipular exceções TypeError} catch (e if e instanceof RangeError) { // declarações para manipular exceções RangeError} catch (e if e instanceof EvalError) { // declarações para manipular exceções EvalError} catch (e) { // declarações para manipular quaisquer exceções não especificadas logMyErrors(e); // passa o objeto de exceção para o manipulador de erro}
E aqui temos como implementar as mesmas "cláusulascatch
condicionais" utilizando apenas JavaScript puro conforme a especificação ECMAScript (obviamente é mais verboso, porém, funciona em qualquer lugar):
try { myroutine(); // pode lançar três tipos de exceções} catch (e) { if (e instanceof TypeError) { // declarações para manipular exceções TypeError } else if (e instanceof RangeError) { // declarações para manipular exceções RangeError } else if (e instanceof EvalError) { // declarações para manipular exceções EvalError } else { // declarações para manipular quaisquer exceções não especificadas logMyErrors(e); // passa o objeto de exceção para o manipulador de erro }}
O identificador de exceção
Quando uma exceção é lançada no blocotry
,exception_var
(ex. oe
dentro decatch (e)
) armazena o valor especificado pela declaraçãothrow
. Você pode usar esse identificador para conseguir informação sobre a exceção que foi lançanda.
Esse identificador é local para a cláusulacatch
. Ou seja, é criado quando a cláusulacatch
é introduzida e após terminar sua excecução o identificador não se torna mais disponível.
A cláusulafinally
A cláusulafinally
é executada após a excecução do blocotry
e da(s) cláusula(s)catch
porém antes das declarações seguintes a declaraçãotry
. Ela sempre é executada, independente se uma exceção for lançada ou capturada.
A cláusulafinally
contém declarações para executarem após a execução do blocotry
e da(s) cláusula(s)catch
porém antes das declarações seguintes a declaraçãotry
. A cláusulafinally
é excutada independente se uma exceção for lançada ou não. Caso uma exceção seja lançada, as declarações no interior da cláusulafinally
são executadas mesmo que nenhumcatch
manipule a exceção.
Você pode utilizar a cláusulafinally
para fazer seu script falhar graciosamente quando uma exceção ocorrer; por exemplo, você pode precisar liberar um recurso que seu script possui vinculado. O exemplo seguinte abre um aquivo e então executa declarações que utilizam o arquivo (server-side JavaScript permite que você acesse arquivos). Se uma exceção for lançada enquanto o arquivo estiver aberto, a cláusulafinally
fecha o arquivo antes que o script falhe.
openMyFile();try { // vincula o recurso writeMyFile(theData);} finally { closeMyFile(); // sempre fecha o recurso}
Exemplos
Blocos try aninhados
Primeiro vamos ver o que acontece com isso:
try { try { throw new Error("oops"); } finally { console.log("finally"); }}catch (ex) { console.error("outer", ex.message);}// Resultado// "finally"// "outer" "oops"
Agora, caso nós já capturamos a exceção no blocotry
interno adicionando um blococatch
try { try { throw new Error("oops"); } catch (ex) { console.error("inner", ex.message); } finally { console.log("finally"); }}catch (ex) { console.error("outer", ex.message);}// Resultado:// "inner" "oops"// "finally"
E agora, vamos relançar o erro.
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);}// Resultado:// "inner" "oops"// "finally"// "outer" "oops"
Qualquer exceção lançada será capturada apenas uma vez pelo blococatch
envolvente mais próximo, a não ser que seja relançada. Obviamente qualquer nova exceção elevada no bloco "interno" (pois código em um blococatch
pode fazer algo que lance), será capturado pelo bloco "externo".
Retornando de um blocofinally
Caso o blocofinally
retorne um valor, esse valor torna-se o valor de retorno do produto detry-catch-finally
inteiro, independente de qualquer declaração return nos blocostry
ecatch
. Isso inclui exceções lançadas dentro do blococatch
:
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);}// Resultado:// "inner" "oops"// "finally"
O "oops" externo não é lançado devido ao retorno do blocofinally
. O mesmo se aplicaria a qualquer valor retornado do blococatch
.