cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - When posting, your subject should be specific and summarize your question. Here are some additional tips on asking a great question. X

Error handling for services and subscriptions

and1
13-Aquamarine

Error handling for services and subscriptions

How is the best way to handle errors of services and subscriptions, also how to add retrying if execution service or subscription is failed?

ACCEPTED SOLUTION

Accepted Solutions
Constantine
17-Peridot
(To:and1)

Hello @and1,

 

Technically speaking you handle errors in the same way as you would do it in Java -- via try/catch mechanism and/or returning null or "empty" values, error codes, etc. The same best practices apply (e.g. don't catch exceptions unless you can do something useful with it). After all ThingWorx is a Java application, it just wraps Java exception handling into JavaScript syntax, but behind the scenes there are still good old java.lang.Exception objects. 

 

To "catch" them in mashups you can use "Show Error Notifications" checkbox. It's a very limited facility, but surprisingly useful and allows to handle majority of real-life errors. For the few remaining use cases we apply the practice of splitting the action into two steps -- input validation and actual execution. The first service validates parameters and produces detailed error reports, that you can use to highlight incorrect values with red color, etc. The second service actually executes the action. It still validates the inputs, but this time if something is wrong it simply throws an exception, that you handle in the mashup via that "Show Error Notifications". Obviously, both services can be implemented as one, but we found that it makes mashup design a bit more cumbersome.

 

To my knowledge, there's no default retry functionality, so you would need to do it yourself, again using that try/catch mechanism. I don't see it done often in the wild, mostly for retrying HTTP requests. With the latest 8.5 versions this may get tricky due to service execution timeouts imposed by the runtime, so you need to make sure that your retries do not exceed 30s (by default).

 

The most sophisticated retry mechanism I've seen (we use it for processing large CSV files) implements a job-like state machine and uses streams to store those jobs. A timer runs every minute, queries the stream for new jobs and processes them, while monitoring its execution time. Once it's approaching 30 seconds limit, it terminates and waits for the next execution. If there was an error while processing a job, the corresponding stream entry is updates with the retry attempt number, and it is retried on the next iteration. In this case the complexity is justified, because this import process runs in unattended mode for hours, so it has to be very resilient. It's an overkill for most of the usual use cases.

 

Finally, using logger.warn and logger.error is obviously a good idea, but here the best practice is more about monitoring those logs -- you should do it regularly, even if the application seems to run smooth.

 

Regards,
Constantine

View solution in original post

1 REPLY 1
Constantine
17-Peridot
(To:and1)

Hello @and1,

 

Technically speaking you handle errors in the same way as you would do it in Java -- via try/catch mechanism and/or returning null or "empty" values, error codes, etc. The same best practices apply (e.g. don't catch exceptions unless you can do something useful with it). After all ThingWorx is a Java application, it just wraps Java exception handling into JavaScript syntax, but behind the scenes there are still good old java.lang.Exception objects. 

 

To "catch" them in mashups you can use "Show Error Notifications" checkbox. It's a very limited facility, but surprisingly useful and allows to handle majority of real-life errors. For the few remaining use cases we apply the practice of splitting the action into two steps -- input validation and actual execution. The first service validates parameters and produces detailed error reports, that you can use to highlight incorrect values with red color, etc. The second service actually executes the action. It still validates the inputs, but this time if something is wrong it simply throws an exception, that you handle in the mashup via that "Show Error Notifications". Obviously, both services can be implemented as one, but we found that it makes mashup design a bit more cumbersome.

 

To my knowledge, there's no default retry functionality, so you would need to do it yourself, again using that try/catch mechanism. I don't see it done often in the wild, mostly for retrying HTTP requests. With the latest 8.5 versions this may get tricky due to service execution timeouts imposed by the runtime, so you need to make sure that your retries do not exceed 30s (by default).

 

The most sophisticated retry mechanism I've seen (we use it for processing large CSV files) implements a job-like state machine and uses streams to store those jobs. A timer runs every minute, queries the stream for new jobs and processes them, while monitoring its execution time. Once it's approaching 30 seconds limit, it terminates and waits for the next execution. If there was an error while processing a job, the corresponding stream entry is updates with the retry attempt number, and it is retried on the next iteration. In this case the complexity is justified, because this import process runs in unattended mode for hours, so it has to be very resilient. It's an overkill for most of the usual use cases.

 

Finally, using logger.warn and logger.error is obviously a good idea, but here the best practice is more about monitoring those logs -- you should do it regularly, even if the application seems to run smooth.

 

Regards,
Constantine

Announcements


Top Tags