Hi Ali,
I've had similar frustrations with this, but I think I can help make sense of it. The way I view it, a task like using a numeric input or changing a property value has a very concrete goal - change the value. If something prevents you from doing so, an exception is thrown.
Scripting functions are very much the opposite - ideally they throw an exception only as a last resort. There are plenty of conceivable reasons you might want a script continue even if writeBlocking does not succeed. The function was built with this in mind. In the docs, you'll see it returns a list of QualityCodes. It's up to us to interpret these codes within our script and throw an exception if needed.
Single tag
If you're writing to a single tag*, there's a simple workaround. Simply use a bidirectional binding in your template parameter, perspective param, etc and change that in your script, rather than using writeBlocking().
(*If you're hardcoding a button or something, this approach can also be used to write multiple tags. It just gets more cumbersome as the number of tags increases.)
# Vision (e.g. template or custom property logic)
write_value = event.source.parent.write_value
event.source.parent.value = write_value
# Perspective
write_value = self.custom.write_value
self.custom.value = write_value
## In either context, the value parameter must be bi-directionally bound to a tag ##
Multiple tags
Here's an example script that will provide an error when writing multiple tags simultaneously. This is particularly useful for templates that are configured to write to a dynamic number of tags.
write_paths = ['tag/path/1', 'tag/path/2']
write_values = [value_1, value_2]
codes = system.tag.writeBlocking(write_paths, write_values)
# check Quality Codes returned from writeBlocking
# if not good, store diagnostic message (if any) and tag path
diags = []
bad_paths = []
for i, code in enumerate(codes):
if code.isNotGood():
diag = code.getDiagnosticMessage()
diags.append(diag)
bad_path = write_paths[i]
bad_paths.append(bad_path)
# if any writes were not good, display an error to the user
if len(diags):
msg = '<HTML>Error writing to the following tags:<BR><BR>'
for i, diag in enumerate(diags):
system.gui.messageBox(diag)
msg = ''.join([
msg,
'Tag: ', bad_paths[i], '<BR>',
'Reason: ', str(diag), '<BR><BR>'
])
system.gui.errorBox(msg)
Note that as written, this script will not stop at the errorBox - errorBox is purely visual. If you need the script to actually stop, you'll want to include exit()
after your error checking.
As a side note for the devs, it would be great if writeBlocking had a flag that caused an exception when it returns anything except Good. It would more or less eliminate my need for the code above.
(Edited for simplicity when writing to a single tag)