Jump to content
Server Maintenance This Week. ×

Error Trapping in scripts


dansmith65

This topic is 4457 days old. Please don't post here. Open a new topic instead.

Recommended Posts

I was just writing some scripts that created related records, and came across an interesting error trapping technique that I thought I'd share...

Sample script before error trapping:


Set Variable [$id; invoice::id]

Go to Layout ["lineItems"]

New Record/Request

Set Field[lineItems::invoiceID; $id]

Set Field[lineItems::anotherField; "some data"]

Set Field[lineItems::andAnotherField; "some more data"]

Go to Layout [original layout]



Here are a few possible error scenarios:
  • user does not have privileges to create new records, script would error at the New Record/Request step, then ask the user if they want to continue the script or cancel it. If the user clicked continue, then it would modify the active line item record (if the user's privileges allowed it).
  • if the found set = 0 when the script started, then the $id variable would be empty, so an empty value is set to the lineItems::invoiceID field. When the record is committed, the fields validation would be triggered (this field should be validated to require a value).
The conclusion here is that either the New Record/Request step or any of the Set Field steps can produce an error, and the script should skip the rest of the record-editing steps, and skip to the Go to Layout step if an error occurs. Here is one way to do that...

  • Allow User Abort [OFF]
    makes sure the script runs to the end, even if an error occurs
  • Exit Loop If [Get( LastError ) <> 0 and Let($LastError = Get( LastError ); true)]
    stops editing record, and saves the error
  • Commit Records/Requests [No dialog]
    some field validation won't be evaluated until the record is commited, without this step, the validation error will occur after the Go to Layout step
  • Revert Record/Request [No dialog]
    If an error did occur, remove the newly created record

It's a strange use of the loop/exit loop if/end loop steps, but I like it much better than a bunch of nested If statements.


Allow User Abort [OFF]

Set Variable [$id; invoice::id]

Go to Layout ["lineItems"]

Loop

	New Record/Request

	Exit Loop If [Get( LastError ) <> 0 and Let($LastError = Get( LastError ); true)]

	Set Field[lineItems::invoiceID; $id]

	Exit Loop If [Get( LastError ) <> 0 and Let($LastError = Get( LastError ); true)]

	Set Field[lineItems::anotherField; "some data"]

	Exit Loop If [Get( LastError ) <> 0 and Let($LastError = Get( LastError ); true)]

	Set Field[lineItems::andAnotherField; "some more data"]

	Exit Loop If [Get( LastError ) <> 0 and Let($LastError = Get( LastError ); true)]

	Commit Records/Requests [No dialog]

	Exit Loop If [Get( LastError ) <> 0 and Let($LastError = Get( LastError ); true)]

	Exit Loop If [True]

End Loop

If [not IsEmpty( $LastError ) and $LastError <> 0]

	Revert Record/Request [No dialog]

	Show Custom Dialog ["Error"; "Line item record was not created."]

End If

Go to Layout [original layout]

Link to comment
Share on other sites

Not sure I like the loop structure. Unnecessary, complicates the code.

Trap the New Record step. If a new record is created, the Set Fields steps should be OK.

Trap the Commit Record step. Field Validation may prevent the record from being saved.

Running the script in a empty found set is not an error as such, but it is something that should be checked for.

Allow User Abort [OFF]

If [ Get( FoundCount ) = 0

Exit Script []

End If

Set Variable [$id; invoice::id]

Go to Layout ["lineItems"]

Set Error Capture [ on ]

New Record/Request

Set Variable [ $error ; Get( LastError ) ]

Set Error Capture [ off ]

If [ $error = 0 ]

Set Field[lineItems::invoiceID; $id]

Set Field[lineItems::anotherField; "some data"]

Set Field[lineItems::andAnotherField; "some more data"]

Set Error Capture [ on ]

Commit Records/Requests [No dialog]

Set Variable [ $error ; Get( LastError ) ]

Set Error Capture [ off ]

If [ $error <> 0 ]

Revert Record [ no dialog ]

End If

End If

Go to Layout [ original layout ]

If [ $error <> 0]

Show Custom Dialog ["Error"; "Line item record was not created."]

End If

Link to comment
Share on other sites

  • 2 weeks later...

Thanks for your feedback Vaughan, it made me think about this a little more. I realized that I don't know what error's could occur during a set field step, as opposed to a commit record step. The only errors I can think of that would happen durring the set field step are for field validation or insufficient privileges. I'm sure there are other errors that I can't think of though. (Actually, if using set field by name, that could error if the field does not exist.)

Regarding field validation errors, some validation options error when the field is set, others when the record is commited...

Validation option ................ when error occurs

----------------------------------------------------

Strict data type ................. set field

Not Empty/Unique/Existing ........ commit record

Value List ....................... set field

In Range ......................... set field

By Calculation ................... commit record

Max # of Char's .................. set field

* There is no error on the set field step if "Only during data entry" validation option is selected.

An error thrown on the set field step does not generate a FileMaker error dialog, whereas an error thrown on the commit record step does.

After seeing this, I still think it's best to test for an error after setting every field, otherwise your script could be failing to set field data and you wouldn't even know about it. I think it's debatable if the Loop method I mentioned in my first post is the best way to do this though. The biggest problem I see with it is that you are using a loop for something it wasn't meant for, which is confusing. But what's the alternative? A nested If/else for every set field step? That seems much worse to me.

Basically, what I have done with the loop steps is created a Try/Catch exception handling system: http://www.w3schools...p_exception.asp

Link to comment
Share on other sites

  • 4 weeks later...

I should have tested for this earlier, but I just realized that the 'Exit Loop If' step does not clear the value of Get( LastError ), so I don't need to save the error to a variable like in my first example. I modified the script below to reflect this.


Allow User Abort [OFF]

Set Variable [$id; invoice::id]

Go to Layout ["lineItems"]

Loop

	New Record/Request

	Exit Loop If [Get( LastError ) <> 0]

	Set Field[lineItems::invoiceID; $id]

	Exit Loop If [Get( LastError ) <> 0]

	Set Field[lineItems::anotherField; "some data"]

	Exit Loop If [Get( LastError ) <> 0]

	Set Field[lineItems::andAnotherField; "some more data"]

	Exit Loop If [Get( LastError ) <> 0]

	Commit Records/Requests [No dialog]

	Exit Loop If [Get( LastError ) <> 0]

	Exit Loop If [True]

End Loop

If [Get( LastError ) <> 0]

	Revert Record/Request [No dialog]

	Show Custom Dialog ["Error"; "Line item record was not created."]

End If

Go to Layout [original layout]

Also, I've been using this technique lately and it came in handy when I was writing a new script and picked the wrong table occurrence for a set field step; rather than the script hiding the error and leaving me wondering what went wrong, it gave me an error, and exited without continuing, which helped me debug the script during development.

Link to comment
Share on other sites

This topic is 4457 days old. Please don't post here. Open a new topic instead.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.