Vamos entender um pouco melhor como as exceções funcionam. Quando ocorre um erro em tempo de execução em uma aplicação PowerBuilder, é disparado um evento da aplicação chamado SystemError(). Você pode visualizar este evento abrindo um objeto "application" (figura abaixo).
![]() |
Objeto "application". |
Se optarmos por utilizar o SystemError() para realizar alguns tratamentos de falhas, com certeza enfrentaremos dificuldades, já que esse evento é disparado fora do local onde o código está sendo executado. Contudo, você pode querer capturar e tratar alguns erros no próprio código de uma interface ou classe. Veja o exemplo de código abaixo. Imagine que estamos tentando capturar, através de uma datawindow, o nickname de um usuário que acabou de logar em um sistema.
String ls_user
ls_user = dw_test.getItemString(1, "NICKNAME_USER") |
Como programador PowerBuilder, você deve saber que, caso esta datawindow não possua tal linha ou coluna solicitadas, a aplicação irá disparar a clássica mensagem "Error: Invalid DataWindow row/column specified at line...". Para realizar o tratamento deste erro no próprio método, precisaremos conhecer o que a linguagem oferece. Veja abaixo detalhes de cada palavra reservada:
TRY
<codificação que pode gerar uma exceção>
CATCH
<codificação que permite capturar e tratar uma exceção>
FINALLY
<codificação que permite encerrar o bloco de código. Ideal para fechamento de conexões, destruição de objetos, etc. >
END TRY
Vamos agora tratar o nosso código:
String ls_user
TRY ls_user = dw_test.getItemString(1, "NICKNAME_USER") CATCH (Throwable aoException) Messagebox ("Falha", "Não foi possível identificar o usuário: " + aoException.getMessage()) CLOSE(THIS) END TRY |
Entenda que, desta forma, ao ser disparada a falha no getItemString(), automaticamente a próxima instrução a ser executada será o CATCH, independente se existir mais codificações ao longo do TRY.
Vamos complementar o código fonte do TRY com mais algumas instruções. Nelas você verá que também é possível lançar exceções manualmente. Desta forma, podemos centralizar o tratamento de outras situações:
String ls_user
TRY ls_user = dw_test.getItemString(1, "NICKNAME_USER") IF ISNULL(ls_user) OR Trim(ls_user) = "" THEN Exception loException loException = CREATE Exception loException.setMessage("O nickname do usuário está nulo ou vazio") THROW (loException) END IF CATCH (Throwable aoException) Messagebox ("Falha", "Não foi possível identificar o usuário: " + aoException.getMessage()) CLOSE(THIS) END TRY |
Métodos que disparam exceções
Para elaboramos códigos com qualidade e organização, é importante conhecermos as boas práticas de programação relacionadas. Quando conhecemos os recursos para tratamento de exceções, já podemos eliminar uma (má) prática que ainda é bastante utilizada. Quantas vezes você codificou um método cujo valor de retorno era um tipo int e sua codificação retornava -1 para indicar falha? Com o tratamento de exceções isto não é mais necessário!
Vamos adaptar o código que vimos anteriormente para que esteja contido em uma função chamada of_getNickname(). O retorno desta função será do tipo "string", ou seja, o nickname do usuário. Se ocorrer algum problema na recuperação desse nickname, vamos evitar retornar uma string vazia ou nula para indicar a falha. Iremos lançar uma nova exceção a fim de indicar ao código de origem (o que invocou a função) que houve uma ação inesperada.
Vamos adaptar o código que vimos anteriormente para que esteja contido em uma função chamada of_getNickname(). O retorno desta função será do tipo "string", ou seja, o nickname do usuário. Se ocorrer algum problema na recuperação desse nickname, vamos evitar retornar uma string vazia ou nula para indicar a falha. Iremos lançar uma nova exceção a fim de indicar ao código de origem (o que invocou a função) que houve uma ação inesperada.
// Função: of_getnickname() Retorno: string
String ls_user TRY ls_user = dw_test.getItemString(1, "NICKNAME_USER") IF ISNULL(ls_user) OR Trim(ls_user) = "" THEN Exception loException loException = CREATE Exception loException.setMessage("O nickname do usuário está nulo ou vazio") THROW (loException) END IF CATCH (Throwable aoException) THROW (aoException) END TRY RETURN ls_user |
Se você já inseriu o código acima para fazer algum teste, perceberá que o PowerBuilder acusou um erro. O motivo disto é porque devemos informar que nossa função of_getnickname() está pronta para tratar exceções. Para definir isto, você precisará preencher o campo "Throws", na especificação da função, com o valor "exception". Veja na imagem abaixo.
Pronto. Agora basta que função de origem faça um tratamento semelhante ao que você vê a seguir.
Caso queira tratar suas exceções mais especificamente, listo abaixo algumas classes de exceção:
Espero que tenha dado uma noção de como construir aplicações com uma estrutura que utiliza tratamento de exceções. Apesar de toda a sintaxe utilizada nos exemplos ter sido em PowerScript, não descarto o aprendizado também para desenvolvedores C#, Java, Visual Basic, etc.
TRY String ls_user = of_getNickname() CATCH (Throwable aoException) Messagebox ("Falha", "Não foi possível identificar o usuário: " + aoException.getMessage()) CLOSE(THIS) END TRY |
Caso queira tratar suas exceções mais especificamente, listo abaixo algumas classes de exceção:
- Throwable - Tratamento mais genérico, englobando todos os erros;
- Exception - Exceções criadas pelo usuário e herdadas do Throwable;
- RuntimeError - Erros de Runtime do PowerBuilder e herdado do Throwable;
- NullObjectError - Referência nula para objetos e herdado do RuntimeError;
- DivideByZeroError - Divisão por zero e herdado do RuntimeError;
- DWRuntimeError - Erros em comandos da Datawindow e herdado do RuntimeError;
- OLERuntimeError - Erros em comandos de Objetos OLE e herdado do RuntimeError;
- CORBASystemException - Erros em comando de objetos CORBA e herdado do RuntimeError.
Espero que tenha dado uma noção de como construir aplicações com uma estrutura que utiliza tratamento de exceções. Apesar de toda a sintaxe utilizada nos exemplos ter sido em PowerScript, não descarto o aprendizado também para desenvolvedores C#, Java, Visual Basic, etc.