Implementando SOAP Exception na Orchestration

Quando trabalhamos com o “SOAP Adapter” ou o “HTTP Adapter”, sendo a Send Port do tipo Request-Response, é uma boa prática a orchestration ser capaz de capturar a descrição dos erros que podem ocorrer nessa chamada.
Quem nunca se deparou com a famosa mensagem de erro: “Error 500 - Internal Server Error” ?
Este artigo pode ser usado tanto com o “SOAP Adapter” quanto com o “HTTP Adapter”, pois os dois acionam o mesmo tipo de exception, o “SOAPException”.
Então Mãos a Obra. Neste artigo iremos trabalhar com o HTTP Adapter.

Criando o Projeto

Pra começar a brincadeira, vamos adicionar a classe System.Web.Services ao projeto.
  1. Crie um novo projeto.
  2. Clique em “Add Reference”.
  3. Na aba “.NET” e procure a classe System.Web.Services e clique em OK.

    image[4]
  4. Adicione um novo schema, apenas com alguns campos.
  5. Adicione uma orchestration e adicione os seguintes shapes e portas:

    image
Note que adicionamos um escopo e um Catch Exception.

Configurando o Exception

  1. Na propriedade “Exception Object Type” do Catch Exception clique na seta e escolha “.NET Exceptions”.
  2. Procure por SoapException, e clique em OK. Deverá aparecer System.Web.Services.Protocols.SoapException.

    image 
  3. Na Propriedade “Exception Object Name”, escolha um nome para o objeto. Nesse exemplo vamos usar “ex”. 

    image
  4. Adicione uma variável e uma mensagem do tipo System.Xml.XmlDocument para recuperar a mensagem de erro.
  5. Adicione um shape de “Message Assignment“ e o código abaixo:
xmlRetStatus.LoadXml(ex.Detail.InnerXml); msgFaultMessage = xmlRetStatus;
O desenho final da orchestration deve ficar assim:
image

Não se esqueça de acrescentar um Nome para aplicação e uma snk.

Compile e faça o deploy do projeto.

Agora precisamos de um site HTTP para testarmos a solução, que está disponivel aqui, bem como o projeto em VS 2008.

A mensagem capturada no exception, deve ser parecida com essa:

<ns0:NACK Type="NACK" xmlns:ns0="http://schema.microsoft.com/BizTalk/2003/NACKMessage.xsd"> <NAckID>{D7FA5048-9E1F-4566-9C1C-55884FD7B278}</NAckID> <ErrorCode>0xc0c0167a</ErrorCode> <ErrorCategory>0</ErrorCategory> <ErrorDescription>O servidor remoto retornou um erro: (500) Erro Interno do Servidor.</ErrorDescription> <ErrorDetail> <HttpErrorDetail xmlns="http://schema.microsoft.com/BizTalk/2004/HttpErrorDetails.xsd"> <Headers>Connection: Close Content-Length: 6317 Cache-Control: private Content-Type: text/html; charset=utf-8 Date: Fri, 23 Jul 2010 17:04:21 GMT Server: ASP.NET Development Server/9.0.0.0 X-AspNet-Version: 2.0.50727 </Headers> <Body>&lt;html&gt; &lt;head&gt; &lt;title&gt;N&amp;#227;o foi poss&amp;#237;vel localizar uma parte do caminho 'C:\PastaInexistente\xmlDoc.xml'.&lt;/title&gt; &lt;style&gt; body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px} b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px} H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red } H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon } pre {font-family:"Lucida Console";font-size: .9em} .marker {font-weight: bold; color: black;text-decoration: none;} .version {color: gray;} .error {margin-bottom: 10px;} .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; } &lt;/style&gt; &lt;/head&gt; &lt;body bgcolor="white"&gt; &lt;span&gt;&lt;H1&gt;Erro de Servidor no Aplicativo '/SitePostXml'.&lt;hr width=100% size=1 color=silver&gt;&lt;/H1&gt; &lt;h2&gt; &lt;i&gt;N&amp;#227;o foi poss&amp;#237;vel localizar uma parte do caminho 'C:\PastaInexistente\xmlDoc.xml'.&lt;/i&gt; &lt;/h2&gt;&lt;/span&gt; &lt;font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif "&gt; &lt;b&gt; Descrição: &lt;/b&gt;Ocorreu uma exceção não tratada durante a execução da atual solicitação da Web. Examine o rastreamento de pilha para obter mais informações sobre o erro e onde foi originado no código. &lt;br&gt;&lt;br&gt; &lt;b&gt; Detalhes da Exceção: &lt;/b&gt;System.IO.DirectoryNotFoundException: N&amp;#227;o foi poss&amp;#237;vel localizar uma parte do caminho 'C:\PastaInexistente\xmlDoc.xml'.&lt;br&gt;&lt;br&gt; &lt;b&gt;Erro de Origem:&lt;/b&gt; &lt;br&gt;&lt;br&gt; &lt;table width=100% bgcolor="#ffffcc"&gt; &lt;tr&gt; &lt;td&gt; &lt;code&gt;&lt;pre&gt; Linha 20: XmlDocument xmlDoc = new XmlDocument(); Linha 21: xmlDoc.LoadXml(xmlData); &lt;font color=red&gt;Linha 22: xmlDoc.Save(@&amp;quot;C:\PastaInexistente\xmlDoc.xml&amp;quot;); &lt;/font&gt;Linha 23: Linha 24: &lt;/pre&gt;&lt;/code&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/table&gt; &lt;br&gt; &lt;b&gt; Arquivo de Origem: &lt;/b&gt; c:\ruth\Projetos\BIZTALK_PROJETOS\SitePostXml\Default.aspx.cs&lt;b&gt; &amp;nbsp;&amp;nbsp; Linha: &lt;/b&gt; 22 &lt;br&gt;&lt;br&gt; &lt;b&gt;Rastreamento de Pilha:&lt;/b&gt; &lt;br&gt;&lt;br&gt; &lt;table width=100% bgcolor="#ffffcc"&gt; &lt;tr&gt; &lt;td&gt; &lt;code&gt;&lt;pre&gt; [DirectoryNotFoundException: N&amp;#227;o foi poss&amp;#237;vel localizar uma parte do caminho 'C:\PastaInexistente\xmlDoc.xml'.] System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +193 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) +1162 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) +66 System.Xml.XmlTextWriter..ctor(String filename, Encoding encoding) +37 System.Xml.XmlDocument.Save(String filename) +77 _Default.Page_Load(Object sender, EventArgs e) in c:\ruth\Projetos\BIZTALK_PROJETOS\SitePostXml\Default.aspx.cs:22 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35 System.Web.UI.Control.OnLoad(EventArgs e) +99 System.Web.UI.Control.LoadRecursive() +50 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627 &lt;/pre&gt;&lt;/code&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/table&gt; &lt;br&gt; &lt;hr width=100% size=1 color=silver&gt; &lt;b&gt;Informações sobre a Versão:&lt;/b&gt;&amp;nbsp;Microsoft .NET Framework Versão:2.0.50727.4927; Versão do ASP.NET:2.0.50727.4927 &lt;/font&gt; &lt;/body&gt; &lt;/html&gt; &lt;!-- [DirectoryNotFoundException]: N&amp;#227;o foi poss&amp;#237;vel localizar uma parte do caminho 'C:\PastaInexistente\xmlDoc.xml'. em System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) em System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) em System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) em System.Xml.XmlTextWriter..ctor(String filename, Encoding encoding) em System.Xml.XmlDocument.Save(String filename) em _Default.Page_Load(Object sender, EventArgs e) na c:\ruth\Projetos\BIZTALK_PROJETOS\SitePostXml\Default.aspx.cs:linha 22 em System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) em System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) em System.Web.UI.Control.OnLoad(EventArgs e) em System.Web.UI.Control.LoadRecursive() em System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) [HttpUnhandledException]: Exce&amp;#231;&amp;#227;o do tipo 'System.Web.HttpUnhandledException' foi acionada. em System.Web.UI.Page.HandleError(Exception e) em System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) em System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) em System.Web.UI.Page.ProcessRequest() em System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) em System.Web.UI.Page.ProcessRequest(HttpContext context) em ASP.default_aspx.ProcessRequest(HttpContext context) na c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\sitepostxml\dbb57a48\a921aed0\App_Web_c14kkcwh.0.cs:linha 0 em System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() em System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) --&gt;</Body> </HttpErrorDetail> </ErrorDetail> </ns0:NACK>

É, vai retornar uma mensagem gigante. :)

Note que no campo “ErrorDescription” mostra o erro genérico “O servidor remoto retornou um erro: (500) Erro Interno do Servidor.”

Porem no campo “Body” ele retorna outro xml estruturado que contem a descrição real do erro: “N&amp;#227;o foi poss&amp;#237;vel localizar uma parte do caminho 'C:\PastaInexistente\xmlDoc.xml'”

O que quer dizer que o servidor tentou gravar alguma coisa em uma pasta que não existe.

Então é isso. Até a próxima!

Seja o primeiro a comentar ;)

Postar um comentário

BizTalk 360

Visitas

Arquivo do blog