Error Reporting in Transacties
Door Jonathan en Bert.
Rapporteren over fouten in een transactie
Claris heeft niet alleen ondersteuning voor transactionele scripts geïntroduceerd, maar ook twee nieuwe functies toegevoegd om scriptfouten te helpen rapporteren: naast de eerbiedwaardige get(LastError) hebben we nu get(LastErrorLocation) en get(LastErrorDetail).
Zoals we hebben besproken in onze blog over praktisch Transactie scripting, kan een Transactie worden teruggedraaid door een expliciete scriptstap (Revert Transaction), of het kan automatisch terugdraaien als het tegen bepaalde fouten aanloopt. Wanneer een Transactie wordt teruggedraaid, worden alle gewijzigde gegevens binnen de Transactie teruggezet in de oorspronkelijke staat, waardoor elk direct bewijs van waarom de Transactie is mislukt wordt uitgewist. Je kunt enkele trucs gebruiken om de voortgang van een Transactie te volgen, zoals het gebruik van sub-scripts om een nieuw venster te openen (buiten de Transactie) om informatie op te slaan. Dit kan echter omslachtig zijn om te coderen en te onderhouden en, als de Transactie automatisch terugdraait, is het misschien niet mogelijk om de fout te achterhalen.
Met de nieuwe functies kunnen we terugkijken en zien wat er fout ging. Ze kunnen erg nuttig zijn, maar ze succesvol implementeren kan een beetje lastig zijn – deze blog bekijkt hoe je er het beste uit kunt halen.
De functies gebruiken
Het eerste dat je moet opmerken is dat je de functies niet in opeenvolgende stappen kunt aanroepen:
Set Variable [ $error ; Value : Get(LastError) ]
Set Variable [ $errorLocation ; Value : Get(LastErrorLocation) ]
Set Variable [ $errorDetail; Value : Get(LastErrorDetail) ]
In de eerste regel vangt de Set Variable stap de foutcode op, maar deze wordt natuurlijk met succes uitgevoerd en genereert zelf een foutcode van 0, waardoor de Get(LastErrorLocation) en Get(LastErrorDetail) functies niets teruggeven, omdat er geen fout was.
In plaats daarvan moet u een Let-instructie gebruiken om ze allemaal tegelijk vast te leggen:
Set Variable [ $error ; Value :
Let([
$errorLocation = Get(LastErrorLocation) ;
$errorDetail = Get(LastErrorDetail)
];
Get(LastError)
)
Wat geven ze terug
Het is verwarrend dat de functies iets andere informatie kunnen teruggeven, afhankelijk van de fout en of het een onmiddellijke, automatische terugdraaiing veroorzaakt, of dat de fout een automatische terugdraaiing veroorzaakt bij de Commit Transaction stap, of dat je een expliciete Revert Transaction stap hebt gebruikt.
Get(LastErrorLocation)
De functie Get(LastErrorLocation) retourneert een lijst met de scriptnaam, de scriptstapnaam (Set Field, Open Record, enz.) en de regel in het script waar de fout optrad.
Als de fout een onmiddellijke omkering veroorzaakte, zal je script rechtstreeks naar de stap Commit Transaction gaan. Anders moet je een expliciete Revert Transaction stap gebruiken om hetzelfde te doen.
In beide gevallen zal de Get(LastErrorLocation) functie na de Commit Transaction stap de stapnaam en het regelnummer van de Commit Transaction stap zelf teruggeven – niet helemaal handig!
Als de fout een onmiddellijke omkering veroorzaakte, dan zal de Get(LastError) functie de verwachte foutcode teruggeven.
Helaas, als je een expliciete Revert Transaction stap hebt gebruikt, zal de Get(LastError) functie 0 teruggeven (omdat de Revert Transaction stap succesvol was). Om dit te voorkomen kun je met de Revert Transaction stap een aangepaste foutcode specificeren (een willekeurig getal tussen 5000 en 5499), die wordt geretourneerd door de Get(LastError) functie na de Commit Transactie stap.
Belangrijk is dat als je een aangepaste foutcode specificeert, je ook een aangepaste foutmelding kunt specificeren-we komen hier later op terug.
Het is ook de moeite waard om op te merken dat, als de fout geen onmiddellijke terugdraaiing veroorzaakt, je de Get(LastErrorLocation) functie kunt aanroepen vóór je Revert Transaction stap, en het zal correct de stapnaam en het regelnummer teruggeven waar de fout zich werkelijk voordeed-definitief nuttig, en nogmaals, we komen hier later op terug.
Get(LastErrorDetail)
The Get(LastErrorDetail) step will only return data when called directly after the Commit Transaction step. In this case, it returns a list comprising the script name, the step name and the line in the script that triggered the revert, and any custom message on the fourth line.
If the error triggered an immediate revert, then great, the step name and script line will match where your error occurred. However, if you used the Revert Transaction step, then the step name and script line will simply tell you where your Revert Transaction step is, as that’s what triggered the revert.
De stap Get(LastErrorDetail) retourneert alleen gegevens als deze direct na de stap Commit Transaction stap wordt aangeroepen. In dit geval retourneert het een lijst die bestaat uit de scriptnaam, de stapnaam en de regel in het script die de terugdraaiing veroorzaakte, en elk aangepast bericht op de vierde regel.
Als de fout een onmiddellijke omkering teweegbracht, dan zullen de stapnaam en de scriptregel overeenkomen met waar de fout zich voordeed. Als je echter de stap Revert Transaction hebt gebruikt, dan zullen de stapnaam en scriptregel je gewoon vertellen waar je stap Revert Transactie is, omdat dat de terugdraaiing heeft geactiveerd.
Geïntegreerde foutrapportage
Het lijkt er dus op dat de functie Get(LastErrorDetail) nuttige informatie retourneert na een onmiddellijke terugdraaiing, maar minder nuttige informatie na een expliciete stap Revert Transaction.
Maak je geen zorgen, want als de fout geen onmiddellijke omkering veroorzaakt, kunnen we Get(LastErrorLocation) gebruiken om een lijst te krijgen met de feitelijke stapnaam en coderegel waar de fout optrad. We kunnen dit dan gebruiken als de aangepaste foutmelding, zolang we maar een aangepaste foutcode opgeven.
Voor de efficiëntie gebruiken we een JSON-array om de locatiegegevens en de foutcode op te slaan, omdat het gemakkelijk is om de informatie later op te halen. We specificeren dan alleen de aangepaste foutcode 5000, zodat we die kunnen gebruiken als aangepaste foutmelding in de stap Revert Transaction.
Na de stap Commit Transaction gebruiken we de functies Get(LastError) en Get(LastErrorDetail).
Als we een gewone foutcode krijgen, weten we dat het een onmiddellijke omkering moet zijn geweest en we gebruiken de eerste drie regels van de Get(LastErrorDetail) lijst om de scriptnaam, stapnaam en coderegel te krijgen.
Als we de foutcode 5000 krijgen, weten we dat het een expliciete terugdraaiing moet zijn geweest en we gebruiken de vierde regel van de Get(LastErrorDetail) lijst om de aangepaste foutmelding te krijgen. Dit is de JSON die we direct na de fout instellen, en we gebruiken dit om de scriptnaam, stapnaam en coderegel te krijgen waar de fout werkelijk optrad, en het belangrijkste is de werkelijke foutcode (niet de aangepaste code 5000 die Get(LastError) teruggaf).
In beide gevallen
In beide gevallen hebben we nu wat nuttige informatie om aan de gebruiker te presenteren (in een aangepast dialoogvenster of als een foutenlogboek) over waarom de Transactie is mislukt.

Het bijgevoegde bestand toont de verschillende manieren waarop de functies werken en onze methode om zowel directe als expliciete omkeringen op te vangen.
Let op – validatiefouten.
Helaas is niets perfect en zijn er twee omstandigheden waarin onze foutrapportagemethode zich niet helemaal gedraagt zoals bedoeld.
Dit eerste geval is als je script een van de kleine aantal stappen aanroept die een onmiddellijke, maar stille, Commit Transaction veroorzaken. De meest voorkomende overtreder is de Re-login stap. Zoals we in onze vorige blog hebben beschreven, als deze binnen een Transactieblok wordt gebruikt, zal de Transactie onmiddellijk worden vastgelegd, maar het script zal doorgaan met het uitvoeren van de volgende stappen binnen het Transactieblok. Dit genereert geen fout en meestal is het enige teken van problemen wanneer de stap Commit Transaction wordt bereikt – dit resulteert in een foutmelding 3 (omdat je een Transactie probeert vast te leggen die al is vastgelegd). In dit geval zal onze methode nog steeds de fout oppikken, maar de Get(LastErrorDetail) functie zal geen informatie teruggeven en dus zal ons foutenrapport beperkt zijn.
Dit tweede geval heeft te maken met validatieregels. Met uitzondering van strikte gegevenstypen, controleert FileMaker geen validatieregels tijdens de uitvoering van stappen binnen het Transactieblok – alle validatie wordt aan het einde uitgevoerd, wanneer de stap Commit Transaction wordt bereikt. Hier kan een schending van een validatieregel ertoe leiden dat de transactie wordt teruggezet met een foutmelding 509. Dit is logisch omdat sommige validatieregels, zoals unieke waarde, moeilijk te beoordelen kunnen zijn binnen het bereik van een Transactie. Ook kunnen aangepaste validatieregels gerelateerde waarden vereisen (die Transacties niet kunnen beoordelen). Het betekent echter wel dat er geen fout wordt gemaakt op het moment dat de gegevens worden ingesteld, zelfs niet als dit wordt gevolgd door een stap Commits Records/Requests vastleggen. Net als in het eerste geval zal onze methode de 509 fout oppikken, maar Get(LastErrorDetail) zal geen informatie teruggeven en dus kunnen we niet melden waar in het Transactieblok de fout optrad.
Heb je onze vorige blog al gelezen? Een praktische handleiding voor transacties in FileMaker