CONNECTED Conference 2023 - Aufzeichnungen jetzt hier verfügbar +++                     

Suche

über alle News und Events

 

Alle News

 

Azure Functions benötigen oft einen...

Weiterlesen

In der heutigen Zeit nehmen Erreichbarkeit,...

Weiterlesen

Viele unserer Kunden überlegen derzeit, was sie in...

Weiterlesen

Lösungsansatz – was benötigt man dafür:

  • Einen...
Weiterlesen

Es gibt im Preview die Möglichkeit Azure Blob...

Weiterlesen

In diesem Blogeintrag werden wir drei sichere und...

Weiterlesen

Im vergangenen Jahr war bei uns in Hamburg viel in...

Weiterlesen

Heutzutage werden Token für die Authentifizierung...

Weiterlesen

Versionsverwaltungssoftware gehört zu den...

Weiterlesen

Das Azure API Management self-hosted Gateway von...

Weiterlesen

How-to: BizTalk Orchestration Shape bei behandelten Exceptions ermitteln

Wenn in einer Orchestration eine Exception geworfen wird, möchte man oft wissen, woher sie kommt. So geht's:

Unbehandelte Exception

Schauen wir zunächst, wie es sich verhält, wenn die Exception ungeschützt ist. Hierzu folgende einfache Orchestration:

 

Im Shape „Unguarded Ex“ wird von uns absichtlich eine ApplicationException durch einen C# Helper geworfen.

public static void ThrowApplicationException(String message)

{

    throw new ApplicationException(message);

}

Die entsprechende Orchestration Instanz wird durch die Exception suspendiert.


In der BizTalk Administration Console kann zu der suspendierten Instanz die Fehlerbeschreibung angeschaut werden. Sehr schön ist der Shape Name „Unguarded Ex“ zu erkennen, aus dem die Exception stammt.


Behandelte Exception

Wie verhält es sich, wenn wir die Exception behandeln wollen?

Hierzu fügen wir der Orchestration einen Scope „Scope RiskyWork“ hinzu, in dem wir die „gefährliche Arbeit“ erledigen. Der Scope erhält einen Exception Handler „Catch Any Exception“ mit folgenden Eigenschaften.

Als Ganzes sieht die Orchestration dann so aus.

Im Exception Handler versuchen wir an den Shape Namen zu kommen, indem wir 2 BizTalk Funktionen miteinander kombinieren.

Microsoft.XLANGs.Core.Context.RootService.ExceptionLocation.ShapeID

Microsoft.XLANGs.Core.Context.RootService.FriendlyNameFromShapeId(shapeId)

Erstere sollte uns eine ShapeId geben, die zweite aus der ShapeId dann den lesbaren Shape Namen. Damit wir diese aufrufen können, benötigen wir im BizTalk Projekt eine Referenz auf Microsoft.XLANGs.RuntimeTypes:

Im Asn_Result Shape sieht das ganze dann so aus:

Das Ergebnis senden wir über einen SendPort ins Dateisystem.

Leider ist das Ergebnis überhaupt nicht zufriedenstellend. Wir erhalten nicht wie erhofft den Shape Namen der Exception (wie man anhand der Bezeichnung „ExceptionLocation.ShapeId“ denken könnte). Wir erhalten stattdessen „Cns_Result“, den Shape Name des Shapes, in dem wir die Exception behandeln.

<ns0:ResultProperties xmlns:ns0="ShapeInfoAtException.ResultProperties">

  <ResultText>Cns_Result</ResultText>

</ns0:ResultProperties>


Die Ursache hierfür ist, dass der „ExceptionLocation.ShapeID“ von der BizTalk Engine gleich als erstes im Shape gesetzt wird, für den Fall, dass es eine unbehandelte Exception gibt. Das hilft uns leider so nicht weiter.


Behandelte Exception mit Shape Name

Um an den Shape Namen dennoch zu kommen, können wir einen FirstChance Exception Handler in der Application Domain des Hosts registrieren. Hierzu setzen wir im Helper Projekt zunächst zwei Referenzen.



Und erweitern den Code wie folgt:

public class Helper

{

    private const String ExtendedDataShapeNameKey = "ExceptionShapeNameForInstance";

   

    static Helper()

    {

        AppDomain.CurrentDomain.FirstChanceException += FirstChanceHandler;

    }

   

    private static void FirstChanceHandler(object sender, FirstChanceExceptionEventArgs e)

    {

        Microsoft.XLANGs.Core.Service rootService = Microsoft.XLANGs.Core.Service.RootService;

        String shapeId = rootService.ExceptionLocation.ShapeID;

        String shapeName = rootService.FriendlyNameFromShapeId(shapeId);

       

        rootService.SetExtendedData(ExtendedDataShapeNameKey, shapeName);

    }

   

    public static String GetExceptionShapeName()

    {

        Microsoft.XLANGs.Core.Service rootService = Microsoft.XLANGs.Core.Service.RootService;

        String shapeName = rootService.GetExtendedData(ExtendedDataShapeNameKey) as String;

        return shapeName;

    }

   

    public static void ThrowApplicationException(String message)

    {

        throw new ApplicationException(message);

    }

}

Im statischen Constructor static Helper() registrieren wir den FirstChanceHandler. Der FirstChanceHandler wird bei jeder aufgetretenen Exception aufgerufen, bevor nach ExceptionHandlern gesucht wird.

Im FirstChanceHandler wird nach der bereits beschriebenen Methode der Shape Name ermittelt und in den ExtendedData der Orchestration Instanz zwischengespeichert.

Im Asn_Result Shape wird der Shape Name dann mit Hilfe der GetExceptionShapeName Methode wieder hervorgeholt und im SendResult eingetragen:



Das finale Ergebnis sieht genau so aus, wie wir erhofft haben.

<ns0:ResultProperties xmlns:ns0="ShapeInfoAtException.ResultProperties">

  <ResultText>Unguarded Ex</ResultText>

</ns0:ResultProperties>


Zusammengefasst ist es uns gelungen, eine Exception zu behandeln und dennoch den Shape Name zu ermitteln, in dem die Exception entstanden ist. Dieser kann geloggt werden und kann bei der Ursachenanalyse sehr hilfreich sein, vorausgesetzt, die Shapes haben schöne Namen ;-)

Viel Spaß beim Coding!

Plamen Petrow
QUIBIQ Schweiz

Ihre Kontaktmöglichkeiten

Sie haben eine konkrete Frage an uns


 

Bleiben Sie immer auf dem Laufenden


 

Mit meinem "Ja" erkläre ich mich mit der Verarbeitung meiner Daten zur Zusendung von Informationen einverstanden. Ich weiß, dass ich diese Erklärung jederzeit durch einfache Mitteilung widerrufen kann. Bei einem Nein an dieser Stelle erhalte ich zukünftig keine Informationen mehr.

© QUIBIQ GmbH · Impressum · Datenschutz