Workflow Debugger
De Workflow Debugger is een tool in de UCT (Ultimo Customisation Tool) waarmee consultants workflows stap voor stap kunnen doorlopen om fouten op te sporen. Dit artikel behandelt hoe je de debugger gebruikt, veelvoorkomende fouten en tips voor effectief debuggen.
Debug instructiebewerken
De eenvoudigste manier om een workflow te debuggen is met de Debug instructie. Deze toont een bericht met de huidige waarde van een property of expressie en stopt de workflow.
<Debug Name="Show value" Message="${Job.HoursCalculated}" />
<Debug Name="Show expression" Message="#{Environment.CurrentDateTime}" />
<Debug Name="Show calculation" Message="#round(3.33335, 2)" />
<Debug Name="Show combined" Message="Job: ${Job.Id}, Status: ${Job.Status}, Equipment: ${Job.Equipment}" />
Belangrijk: Debug werkt ALLEEN in Development- of Test-omgevingen. In Productie veroorzaakt een Debug instructie een foutmelding en stopt de workflow. Verwijder altijd alle Debug instructies voor je naar productie gaat.
Debuggen in UCTbewerken
Workflow editorbewerken
- Open UCT en navigeer naar de workflow die je wilt debuggen
- Open de workflow in de editor
- Bekijk de XML structuur en controleer:
- Zijn alle properties correct gedeclareerd?
- Staan database-operaties binnen een Transaction?
- Zijn de XML-escapes correct (
&&,<,>)? - Publiceer de workflow na wijzigingen
Stappen voor effectief debuggenbewerken
- Reproduceer het probleem - Bepaal welke actie (statuswijziging, import, etc.) het probleem triggert
- Identificeer de workflow - Op basis van de naamconventie (
Entity_TriggerType) weet je welke workflow wordt uitgevoerd - Voeg Debug instructies toe - Plaats Debug instructies op strategische punten om waarden te inspecteren
- Test stapsgewijs - Verplaats de Debug instructie steeds verder in de workflow om het exacte punt van de fout te vinden
- Controleer UserContent - Vergeet niet dat Pre en Post UserContent secties ook code bevatten
- Verwijder Debug - Verwijder alle Debug instructies na het oplossen
Veelvoorkomende foutenbewerken
1. Database operatie buiten Transactionbewerken
Fout: GetList, Insert, ChangeStatus etc. buiten een Transaction blok geplaatst.
Symptoom: Foutmelding dat er geen actieve sessie is.
Oplossing:
<!-- FOUT -->
<GetList Name="Get jobs" Type="Job" OutputProperty="${Jobs}" />
<!-- GOED -->
<Transaction>
<GetList Name="Get jobs" Type="Job" OutputProperty="${Jobs}" />
</Transaction>
2. Assign gebruikt voor statuswijzigingbewerken
Fout: Status wijzigen via Assign in plaats van ChangeStatus.
Symptoom: Status is gewijzigd maar Pre/Post workflows zijn niet uitgevoerd, data is inconsistent.
Oplossing:
<!-- FOUT - Status Matrix wordt niet gevolgd -->
<Assign Name="Set status" Property="${Job.Status}" Value="JobStatus.Active" />
<!-- GOED - Status Matrix en Pre/Post workflows worden correct doorlopen -->
<ChangeStatus Name="Activate" DomainObject="${Job}" NewStatus="JobStatus.Active" />
3. XML escape foutenbewerken
Fout: Speciale tekens niet geescaped in XML condities.
Symptoom: XML parse error, workflow kan niet geladen worden.
Oplossing:
<!-- FOUT -->
<When Condition="${Value} > 100 && ${Value} < 200">
<!-- GOED -->
<When Condition="${Value} > 100 && ${Value} < 200">
Veel voorkomende XML escapes:
| Teken | XML escape |
|---|---|
& |
& |
< |
< |
> |
> |
" |
" |
&& |
&& |
4. Property type mismatchbewerken
Fout: Een property vergelijken met een waarde van een ander type.
Symptoom: Onverwachte resultaten in When-condities, of runtime foutmelding.
Oplossing: Controleer altijd het type van de property in de Object Dictionary. Gebruik conversie-functies zoals #tostring(), #todecimal(), #tointeger() waar nodig.
5. Lege property referentiebewerken
Fout: Toegang tot een property van een object dat Empty is.
Symptoom: NullReferenceException of onverwacht gedrag.
Oplossing:
<!-- FOUT - kan crashen als Equipment empty is -->
<Assign Name="Set" Property="${Target}" Value="${Job.Equipment.Description}" />
<!-- GOED - eerst controleren -->
<When Name="Equipment aanwezig" Condition="${Job.Equipment} != Empty">
<Assign Name="Set" Property="${Target}" Value="${Job.Equipment.Description}" />
</When>
6. ForEach op een lege of null lijstbewerken
Fout: ForEach op een lijst die niet is geinitialiseerd.
Symptoom: Foutmelding over null reference.
Oplossing: Controleer altijd of de lijst gevuld is:
<When Name="Lijst niet leeg" Condition="${JobList} != Empty && ${JobList.Count} > 0">
<ForEach Name="Loop" In="${JobList}" As="Item">
<!-- acties -->
</ForEach>
</When>
7. Oneindige lus in Whilebewerken
Fout: While-conditie wordt nooit false.
Symptoom: Workflow loopt vast tot de CycleLimit wordt bereikt.
Oplossing: - Zorg ervoor dat de conditie-variabele binnen de lus wordt gewijzigd - Stel altijd een CycleLimit in - Gebruik Debug om de conditie-waarde te monitoren
8. Email zonder ontvangerbewerken
Fout: Email instructie waarbij de ontvanger geen emailadres heeft.
Symptoom: Workflow foutmelding.
Oplossing:
<When Name="Heeft email" Condition="${Job.Employee} != Empty && ${Job.Employee.EmailAddress} != Empty">
<Email Name="Send" From="#{Settings.EmailSender}" To="${Job.Employee}" EmailTemplateCode="9001" />
</When>
9. MessageCode niet gevondenbewerken
Fout: Validation of Message verwijst naar een MessageCode die niet in de database staat.
Symptoom: Foutmelding of lege melding aan de gebruiker.
Oplossing: Voeg de message toe via UCT > Messages. Custom messages gebruiken codes vanaf 9000.
10. UserContent in Bulk workflow niet in ForEachbewerken
Fout: UserContent direct in de Execution van een Bulk workflow.
Symptoom: Foutmelding bij publicatie.
Oplossing: In Bulk workflows moet UserContent een descendant van ForEach zijn.
Tips voor effectief debuggenbewerken
Gebruik Log voor productie-monitoringbewerken
In productie kun je geen Debug gebruiken, maar wel Log:
<Log Name="Monitor" Description="Job ${Job.Id} verwerkt, status: ${Job.Status}"
LogName="CustomWorkflow" Type="Information" />
Gebruik Comment voor documentatiebewerken
Voeg Comment instructies toe om complexe logica te documenteren:
<Comment Comment="Business rule BR-001"><![CDATA[
Als een job wordt goedgekeurd met een kostenplaats > 50.000 EUR,
moet er een extra goedkeuring door de directie plaatsvinden.
Zie functioneel ontwerp FO-2024-001.
]]></Comment>
Test met specifieke scenario'sbewerken
- Test het "happy path" (alles correct ingevuld)
- Test met lege/ontbrekende waarden
- Test met grenswaarden (maximale lijsten, lange teksten)
- Test zonder user interaction (simuleert import/scheduler)
Controleer de workflow volgordebewerken
Bij een statuswijziging worden meerdere workflows in een vaste volgorde uitgevoerd:
Entity_Pre{NewStatus}(Pre UserContent Pre -> standaard logica -> Pre UserContent Post)- Statuswijziging in database
Entity_Post{NewStatus}(Post UserContent Pre -> standaard logica -> Post UserContent Post)
Gebruik Debug of Log om te verifieren in welke workflow en welk punt je zit.
Controleer Settingsbewerken
Veel workflows gebruiken #{UltimoSettings.XXX} of #settingenabled(). Controleer de waarde van deze settings in UCT > Settings:
<Debug Name="Check setting" Message="#getsetting(${Job}, 'Job.RoundHours')" />
Gerelateerde artikelenbewerken
- workflow-engine - Overzicht van de workflow engine
- workflow-instructies - Alle instructies inclusief Debug
- workflow-patronen - Veelvoorkomende patronen
- expressions - Expression functies voor condities