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

Suche

über alle News und Events

 

Alle News

 

Für Entwickler, Architekten, Projektleiter und...

Read more

In der Welt der Softwareentwicklung ist die...

Read more

QUIBIQ spendet für den guten Zweck – und für...

Read more

Eine bestimmte Antwort auf einen HTTP Request zu...

Read more

In einer Welt, die von stetigem Wandel geprägt...

Read more

In einem unserer Kundenprojekte, war das Ziel eine...

Read more

QUIBIQ Hamburg wird mit dem Hamburger...

Read more

Zwei Tage lang wurde vom 14.-15.11 wieder das...

Read more

Was ist ein Excel-Plugin – und wann ist es...

Read more

Wir expandieren, bringen Kunden und Talente besser...

Read more

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