Manipulação de erros síncronos em um aplicativo

Flash Player 9 e posterior, Adobe AIR 1.0 e posterior

A manipulação de erros mais comum é a lógica de manipulação de erros síncrona, em que você insere instruções no código para detectar erros síncronos enquanto um aplicativo está em execução. Esse tipo de manipulação de erros permite ao aplicativo notar e se recuperar de erros de tempo de execução quando as funções falham. A lógica para detectar um erro síncrono inclui as instruções try..catch..finally , que literalmente tentam uma operação, detectam qualquer resposta de erro do tempo de execução do Flash e finalmente executam outra operação para manipular a operação que falhou.

Uso das instruções try..catch..finally

Durante o trabalho com erros de tempo de execução síncronos, use as instruções try..catch..finally para detectar erros. Quando ocorre um erro de tempo de execução, o tempo de execução do Flash lança uma exceção, o que significa que ele suspende a execução normal e cria um objeto especial do tipo Error. O objeto Error é lançado para o primeiro bloco catch disponível.

A instrução try delimita instruções com potencial para criar erros. A instrução catch é sempre usada com uma instrução try . Se for detectado um erro em uma das instruções no bloco try , as instruções catch anexadas a try serão executadas.

A instrução finally delimitará as instruções que serão executadas caso ocorra ou não um erro no bloco try . Se não houver nenhum erro, as instruções no bloco finally serão executadas depois que as instruções do bloco try forem concluídas. Se houver um erro, a instrução catch apropriada será executada primeiro, seguida pelas instruções no bloco finally .

O código a seguir demonstra a sintaxe para usar as instruções try..catch..finally :

try 
{ 
    // some code that could throw an error 
} 
catch (err:Error) 
{ 
    // code to react to the error 
} 
finally 
{ 
    // Code that runs whether an error was thrown. This code can clean 
    // up after the error, or take steps to keep the application running. 
}

Cada instrução catch identifica um tipo específico de exceção que ela manipula. A instrução catch pode especificar apenas as classes de erro que forem subclasses da classe Error. Cada instrução catch é verificada por ordem. Somente a primeira instrução catch que corresponder ao tipo de erro gerado será executada. Em outras palavras, se você verificar primeiro a classe Error de alto nível e depois uma subclasse dela, somente a classe Error de alto nível será correspondente. O seguinte código ilustra essa questão:

try 
{ 
    throw new ArgumentError("I am an ArgumentError"); 
} 
catch (error:Error) 
{ 
    trace("<Error> " + error.message); 
} 
catch (error:ArgumentError) 
{ 
    trace("<ArgumentError> " + error.message); 
}

O código anterior exibe a seguinte saída:

<Error> I am an ArgumentError

Para detectar corretamente o ArgumentError, os tipos de erro mais específicos devem ser listados primeiro e os mais genéricos por último, como mostra o seguinte código:

try 
{ 
    throw new ArgumentError("I am an ArgumentError"); 
} 
catch (error:ArgumentError) 
{ 
    trace("<ArgumentError> " + error.message); 
} 
catch (error:Error) 
{ 
    trace("<Error> " + error.message); 
}

Vários métodos e propriedades na API do ActionScript lançam erros de tempo de execução quando encontram erros ao serem executados. Por exemplo, o método close() na classe Sound lançará um IOError se o método não conseguir fechar o fluxo de áudio, conforme demonstrado no seguinte código:

var mySound:Sound = new Sound(); 
try 
{ 
    mySound.close(); 
} 
catch (error:IOError) 
{ 
    // Error #2029: This URLStream object does not have an open stream. 
}

À medida que você se familiariza com a Referência do ActionScript® 3.0 para Adobe® Flash® Platform , irá perceber quais métodos geram exceções, como detalhado na descrição de cada método.

A instrução throw

Os tempos de execução do Flash lançam exceções quando encontram erros no seu aplicativo em tempo de execução. Além disso, você mesmo pode lançar exceções explicitamente usando a instrução throw . Ao lançar erros explicitamente, a Adobe recomenda que você lance ocorrências da classe Error ou de suas subclasses. O código a seguir demonstra uma instrução throw que lança uma ocorrência da classe Error, MyErr e finalmente chama uma função, myFunction() , para responder depois que o erro é lançado:

var MyError:Error = new Error("Encountered an error with the numUsers value", 99); 
var numUsers:uint = 0; 
try 
{ 
    if (numUsers == 0) 
    { 
        trace("numUsers equals 0"); 
    } 
} 
catch (error:uint) 
{ 
    throw MyError; // Catch unsigned integer errors. 
} 
catch (error:int) 
{ 
    throw MyError; // Catch integer errors. 
} 
catch (error:Number) 
{ 
    throw MyError; // Catch number errors. 
} 
catch (error:*) 
{ 
    throw MyError; // Catch any other error. 
} 
finally  
{ 
    myFunction(); // Perform any necessary cleanup here. 
}

Observe que as instruções catch são ordenadas de forma que os tipos de dados mais específicos sejam listados primeiro. Se a instrução catch do tipo de dados Number for listada primeiro, a instrução catch para o tipo de dados uint e a instrução catch para o tipo de dados int nunca serão executadas.

Nota: Na linguagem de programação Java, cada função que pode lançar uma exceção deve declarar esse fato, listando as classes de exceção que pode lançar em uma cláusula throws anexada à declaração de função. O ActionScript não requer que você declare as exceções geradas por uma função.

Exibição de uma mensagem de erro simples

Uma das grandes vantagens do novo modelo de eventos de exceção e erro é que ele permite dizer aos usuários quando e por que uma ação falhou. Cabe a você escrever o código para exibir a mensagem e oferecer opções em resposta.

O código a seguir mostra uma instrução try..catch simples para exibir o erro em um campo de texto:

package 
{ 
    import flash.display.Sprite; 
    import flash.text.TextField; 
     
    public class SimpleError extends Sprite 
    { 
        public var employee:XML =  
            <EmpCode> 
                <costCenter>1234</costCenter> 
                <costCenter>1-234</costCenter> 
            </EmpCode>; 
 
        public function SimpleError() 
        { 
            try 
            { 
                if (employee.costCenter.length() != 1) 
                { 
                    throw new Error("Error, employee must have exactly one cost center assigned."); 
                } 
            }  
            catch (error:Error) 
            { 
                var errorMessage:TextField = new TextField(); 
                errorMessage.autoSize = TextFieldAutoSize.LEFT; 
                errorMessage.textColor = 0xFF0000; 
                errorMessage.text = error.message; 
                addChild(errorMessage); 
            } 
        } 
    } 
}

Usando uma ampla variedade de classes de erro e erros do compilador embutidos, o ActionScript 3.0 oferece mais informações do que as versões anteriores do ActionScript sobre o motivo de uma falha. Essa informação permite criar aplicativos mais estáveis com uma manipulação de erros melhor.

Relançamento de erros

Ao criar aplicativos, há várias ocasiões em que pode ser preciso relançar um erro quando não é possível manipulá-lo adequadamente. Por exemplo, o código a seguir mostra um bloco try..catch aninhado, que relança um ApplicationError personalizado quando o bloco catch não consegue manipular o erro:

try 
{ 
    try 
    { 
        trace("<< try >>"); 
        throw new ApplicationError("some error which will be rethrown"); 
    } 
    catch (error:ApplicationError) 
    { 
        trace("<< catch >> " + error); 
        trace("<< throw >>"); 
        throw error; 
    } 
    catch (error:Error) 
    { 
        trace("<< Error >> " + error); 
    } 
} 
catch (error:ApplicationError) 
{ 
    trace("<< catch >> " + error); 
}

O resultado do snippet anterior seria o seguinte:

<< try >> 
<< catch >> ApplicationError: some error which will be rethrown 
<< throw >> 
<< catch >> ApplicationError: some error which will be rethrown

O bloco try aninhado lança um erro ApplicationError personalizado que é detectado pelo bloco catch subsequente. Esse bloco catch aninhado pode tentar manipular o erro e, se for bem-sucedido, lançará o objeto ApplicationError ao bloco try..catch delimitador.