﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>egomesbrandao, blog &#187; exception</title>
	<atom:link href="http://egomesbrandao.net/blog/tag/exception/feed/" rel="self" type="application/rss+xml" />
	<link>http://egomesbrandao.net/blog</link>
	<description>.net, scrum, scripts e afins...</description>
	<lastBuildDate>Tue, 11 Oct 2011 20:38:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>ABC App &#8211; 04 Exceções</title>
		<link>http://egomesbrandao.net/blog/2009/11/abc-app-04-excecoes/</link>
		<comments>http://egomesbrandao.net/blog/2009/11/abc-app-04-excecoes/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 20:01:15 +0000</pubDate>
		<dc:creator>egomesbrandao</dc:creator>
				<category><![CDATA[abcapp]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[camadas]]></category>
		<category><![CDATA[entlib]]></category>
		<category><![CDATA[exception]]></category>

		<guid isPermaLink="false">http://egomesbrandao.net/blog/?p=109</guid>
		<description><![CDATA[Ia deixar para escrever sobre o assunto depois, mas pra começar bem a semana vou usar o comentário do Tucaz e fazer um Refactoring no código e tratar Execeptions, ou Exceções! exceção ex.ce.ção sf (lat exceptione) 1 Ato ou efeito de excetuar. 2 Desvio de regra, de lei, de princípio ou de ordem. 3 A [...]]]></description>
			<content:encoded><![CDATA[<p>Ia deixar para escrever sobre o assunto depois, mas pra começar bem a semana vou usar o comentário do <a href="http://blog.tucaz.net/" target="_blank">Tucaz</a> e fazer um <em>Refactoring</em> no código e tratar <em>Execeptions</em>, ou Exceções!</p>
<blockquote><p>exceção<br />
ex.ce.ção<br />
sf (lat exceptione) 1 Ato ou efeito de excetuar. 2 Desvio de regra, de lei, de princípio ou de ordem. 3 A coisa excetuada; aquilo que se desvia da regra. 4 Prerrogativa, privilégio. 5 Pessoa cujo modo de pensar ou de proceder se afasta do comum e usual. 6 Dir Alegação jurídica, constituindo defesa indireta (difere da contestação, que é defesa direta), pela qual o réu pretende baldar a ação intentada. E. declinatória, Dir: a que visa a declinar a competência do juiz ou tribunal ao qual foi apresentada a demanda. E. dilatória, Dir: a que pretende apenas demorar a demanda. E. peremptória, Dir: a que de todo e definitivamente afasta a demanda.</p></blockquote>
<p>Conforme a <a href="http://michaelis.uol.com.br/moderno/portugues/index.php?lingua=portugues-portugues&amp;palavra=exceção" target="_blank">definição acima do Michaelis</a>, exceção é um desvio da regra. Na classe Customer da camada de DAL, quando fazemos acesso ao banco de dados para buscar um ou mais usuários, a EntLib abre uma conexão e executa o comando Select, essa é a regra, mas e quando o banco de dados não esta disponível? Ou se alguém renomeou ou apagou a tabela que esta na nossa query? Isso são exceções, e se não tratarmos, o sistema para de funcionar! Para testar é só desligar o banco de dados (parando o serviço SQL Server Browser) e rodar o nosso software.</p>
<p>Existem várias correntes de pensamento sobre <em>Exceptions</em></p>
<p>Devemos tratar Exceptions como conexões a banco de dados, mas se um usuário do sistema cadastrar um número inválido de CPF devemos lançar uma <em>Exeception</em>? Devemos criar nossas próprias <em>Execeptions</em> para o nosso sistema? Onde devemos tratar? Muitas perguntas, algumas vão ficar sem respostas no momento, o objetivo desse post será fazer o <em>Refactoring</em>, e o primeiro será na conexão do banco.</p>
<p>Tratamento de <em>Exceptions</em></p>
<p>No .Net é usado a tríade Try-Catch-Finally, o código passível de erro e que pode vir a lançar uma exceção é colocado no bloco do Try, no Catch é onde se pegam as execeções, e o Finally serve para finalizar alguma operação, limpar alguma variável,  e, muitas vezes,  ele não é usado, mas no nosso primeiro exemplo já faremos uso dele.<br />
Uma regra que devemos sempre atentar é: nunca, NUNCA, colocar um método inteiro dentro de um bloco Try, não há necessidade de colocar criação de variáveis! Teste somente o que pode dar um erro. Além disso,  o código fica mais elegante.</p>
<p>No código da classe Customer da camada de DAL o que pode dar erro? O mais óbvio seria quando o DataReader estivesse sendo carregado, se nessa hora o banco de dados cair o nosso software vai pro espaço! Como no método AdaptToList ainda usamos o DataReader (ele fica aberto para popularmos o objeto Customer)  vamos colocar a linha de ExecuteReader e a de chamada do AdaptToLista dentro do Try. Para fazer isso,  vamos usar o recurso de <em>Refactoring</em> da IDE :  selecione as duas linhas, clique CTRL, e no menu de contexto escolha Surrond With&#8230;</p>
<div id="attachment_112" class="wp-caption aligncenter" style="width: 568px"><img class="size-full wp-image-112" title="ABC App 04 - Imagem01" src="http://egomesbrandao.net/blog/wp-content/uploads/2009/11/ABCApp04_Imagem01.png" alt="Fazendo um Surrond With no código" width="558" height="356" /><p class="wp-caption-text">Fazendo um Surrond With no código</p></div>
<p>Escolha a opção &#8220;tryf&#8221;, conforme figura abaixo, repare que este é um atalho para um Snippet, então quando estiver escrevendo código usando este atalho economiza tempo!</p>
<div id="attachment_113" class="wp-caption aligncenter" style="width: 561px"><img class="size-full wp-image-113" title="ABC App 04 - Imagem02" src="http://egomesbrandao.net/blog/wp-content/uploads/2009/11/ABCApp04_Imagem02.png" alt="Escolha &quot;tryf&quot;" width="551" height="249" /><p class="wp-caption-text">Escolha &quot;tryf&quot;</p></div>
<p>O código estará dentro do bloco Try, veja outras alterações no código abaixo e em seguida o por quê</p>
<pre class="brush: csharp; title: ;">
public Domain.Customer GetCustomerById(int customerId)
        {
            IDataReader dr = null;
            IList&lt;Domain.Customer&gt; lstCustomers = null;

            string sql = &quot;select customerid, firstname, middlename, lastname, companyname, emailaddress, phone, modifieddate from saleslt.customer where customerid = @customerid&quot;;

            DbCommand cmd = db.GetSqlStringCommand(sql);

            db.AddInParameter(cmd, &quot;customerid&quot;, DbType.Int32, customerId);

            try
            {
                dr = db.ExecuteReader(cmd);
                lstCustomers = AdaptToList(dr);
            }
            catch (System.Data.SqlClient.SqlException exsql)
            {
                throw new Exception(exsql.Message);
            }
            catch {
            }

            finally
            {
                if (!dr.IsClosed)
                    dr.Close();
            }

            return ((lstCustomers != null) || (lstCustomers[0] != null)) ? lstCustomers[0] : null;
        }
}
</pre>
<p>Listagem 01</p>
<p>Movi a declaração do DataReader para o início do método, pois podemos deixar dentro do Try, já que o Finally não iria enxergar esse objeto e depois é só mover a linha que faz a verificação se o DataReader estiver aberto para dentro do Finally, ocorrendo ou não um erro o Finally sempre é executado e daí ele ficará responsável por fechar o DataReader.<br />
O Tucaz também fez um comentário sobre setar o CommandBehavior para CloseConnection, o que faria a conexão com o banco ser fechada após fecharmos o DataReader, mas a EntLib cuida disso pra gente! Veja o código fonte, e essa é a parte legal de usar essa biblioteca da MS, pois com o acesso ao fonte vemos as boas práticas sendo aplicadas, aquelas que se encontram no <a href="http://msdn.microsoft.com/en-us/library/ms978510.aspx" target="_blank">Guia de Acesso a Dados</a>.<br />
O Catch vazio vai pegar todo o tipo de exceção, então é bom especializarmos o Catch, por isso eu também coloquei para pegar a SQLException.</p>
<p><strong>Aplique esse <em>Refactoring</em> no método GetCustomers() também.</strong></p>
<p>OK&#8230; E vamos fazer isso também quando é criado o Database na classe BaseDAL, pois se o banco de dados estiver fora do ar vai dar um erro. É só executar os mesmos passos em cima da única linha que temos no único construtor da classe. E vai ficar assim:</p>
<pre class="brush: csharp; title: ;">
    public abstract class BaseDAL
    {
        public EntLib.Database db { get; set; }

        public BaseDAL()
        {
            try
            {
                db = EntLib.DatabaseFactory.CreateDatabase(&quot;Connection String&quot;);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {

            }
        }
    }
</pre>
<p>Listagem 02<br />
E agora temos que exibir esses erros lá na nossa interface de usuário, aqui vai o código de como vai ficar:</p>
<pre class="brush: csharp; title: ;">

namespace ABCApp.Console
{
    class Program
    {
        static void Main(string[] args)
        {

            ABCApp.Domain.Customer c;

            ABCApp.DAL.Customer dalCustomer = new ABCApp.DAL.Customer();

            try
            {
                c = dalCustomer.GetCustomerById(1);
                System.Console.WriteLine(c.CustomerId.ToString() + &quot; - &quot; + c.FirstName.ToString() + &quot; &quot; + c.LastName.ToString());
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }

            System.Console.ReadKey();

            try
            {
                IList&lt;Domain.Customer&gt; lstCustomer = dalCustomer.GetCustomers();

                foreach (Domain.Customer customer in lstCustomer)
                {
                    System.Console.WriteLine(customer.CustomerId.ToString() + &quot; - &quot; + customer.FirstName.ToString() + &quot; &quot; + customer.LastName.ToString());
                }
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }
         �
            System.Console.ReadKey();
        }
    }
}
</pre>
<p>Vamos testar? Para isso desligue o seu SQL Server! Vá no menu Iniciar &gt; Microsoft SQL Server 2008 &gt; Configuration Tools &gt; SQL Server Configuration Manager, entre na ferramenta.  Pare o serviço SQL Server Browser, daí não deve ser possível conectar na base. Rodando a aplicação devem ser impressas mensagens de erro onde deveriam aparecer dados!</p>
<p>Bom&#8230; Isso foi só para começarmos a colocar um controle sobre os locais onde podem ocorrer <em>Exceptions</em>, esse não é o mundo perfeito, e nem será a última vez que irei falar sobre o tema. Mas por que não ler alguns links sobre isso? Aí vai:</p>
<p><a href="http://unplugged.giggio.net/unplugged/post/Como-tratar-erros.aspx">http://unplugged.giggio.net/unplugged/post/Como-tratar-erros.aspx</a></p>
<p><a href="http://msdn.microsoft.com/en-us/library/dd203116.aspx">http://msdn.microsoft.com/en-us/library/dd203116.aspx</a> (Esse é sobre o bloco de Exceptions da EntLib, mais pra frente vamos usar ele)</p>
<p><a href="http://www.developerfusion.com/article/5250/exceptions-and-performance-in-net/">http://www.developerfusion.com/article/5250/exceptions-and-performance-in-net/</a> (discute a questão de performance ao lançar exceções)</p>
<p><a href="http://yoda.arachsys.com/csharp/exceptions2.html">http://yoda.arachsys.com/csharp/exceptions2.html</a> (também sobre performance)</p>
<p><a href="http://www.artima.com/interfacedesign/AbnormalConditions.html">http://www.artima.com/interfacedesign/AbnormalConditions.html</a></p>
<p><a href="http://apparch.codeplex.com/">http://apparch.codeplex.com/</a> (aqui tem um vídeo sobre o tema)</p>
<p>Fico por aqui&#8230; Na quinta-feira post sobre objetos anêmicos&#8230;</p>
<p>O código deste post esta no <a href="http://abcapp.codeplex.com/SourceControl/changeset/view/36605" target="_blank">Change Set 36605</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://egomesbrandao.net/blog/2009/11/abc-app-04-excecoes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

