Retry Utility Hook After Fail

dansmith65:
I have some important data that really needs to be sent from the user’s session to FMS, even if it fails the first time for some reason. Is there any way I can write some code to make it try sending a utility hook again if it happens to fail for some reason?


Andrew Dam:
@Delfs may be able to provide some more insight on this.


Delfs:
Yeah I think you can do something like this
named Actions: repeat sender
• runHook
• Function check for positive result if good clearActions
• Delay 500mS
• Call NamedAction repleastSender


dansmith65:
Thanks! But I don’t think I know how to check for positive result. I’m not sure if I should be doing something like wait for a promise to resolve, or maybe just look for a value in the model that the hook sets, maybe?


Delfs:
You can check the model for something model.didSave and set that in server.


dansmith65:
If that utility hook adds actions, do they run before an action defined in BF right after calling the hook?


Delfs:
Actually, what I would do is use some data in the model, but yes, do utility hook actions that are added by the server are put on the top of the stock versus on the end so should run first


dansmith65:
Thanks for your help with this; I just got around to implementing it today and it seems to do the job. In case anyone else wants this functionality, I’ve attached my named actions. I kick off the process by calling pay_processResponse. The hook script just needs to set model.pay_processResponse.completed to stop the loop. The retry logic times out after 5 minutes.

"pay_processResponse": [{
	"action": "namedAction",
	"name": "clearValidateInvoiceTimer"
}, {
	"action": "showModal",
	"nonBlocking": true,
	"options": {
		"body": "<i class=\"fa fa-spinner fa-spin fa-3x fa-fw\"></i> Processing payment...",
		"icon": "",
		"options": {
			"blocking": true,
			"buttons": [],
			"hideCloseButton": true
		},
		"overlayTheme": "dark"
	}
}, {
	"action": "namedAction",
	"function": "model.pay_processResponseLoop = {startTime: new Date()}",
	"name": "pay_processResponseLoop"
}],
"pay_processResponseLoop": [{
	"action": "runUtilityHook",
	"function": "model.pay_processResponse = {completed: false}",
	"options": {
		"modelFilterKeys": ["invoice", "businessOrIndividual", "name", "address"],
		"type": "pay_processResponse"
	}
}, {
	"action": "function",
	"function": "if (model.pay_processResponse?.completed) {\n    if (vueapp.$store.state.site.content.devMode) {\n        console.log('pay_processResponseLoop: hook completed, clearning action queue now, actions:', vueapp.$store.state.actions.actions)\n    }\n    BF.actionsClear()\n} else {\n    var timeOutMS = 1000 * 60 * 5\n    var runtime = (Date.now() - moment(model.pay_processResponseLoop.startTime)) /* in milliseconds */\n    var timedOut = runtime > timeOutMS\n    \n    if (vueapp.$store.state.site.content.devMode) {\n        console.log('pay_processResponseLoop: hook did not set the proper model key')\n    }\n    if (timedOut) {\n        BF.actionsClear()\n        vueapp.$store.dispatch('ACTIONS_QUEUE', [{\n            \"action\": \"showModal\",\n            \"options\": {\n                \"body\": \"Sorry, something went wrong when saving this payment. Your card may have been charged, even though the Invoice won't show as paid. Please let us know about this error so we can correct it.\",\n                \"icon\": \"error\",\n                \"overlayTheme\": \"dark\",\n                \"title\": \"Error!\"\n            }\n        }])\n        console.error('pay_processResponseLoop: timed out')\n    }\n}"
}, {
	"action": "wait",
	"options": {
		"ms": 2000
	}
}, {
	"action": "namedAction",
	"name": "pay_processResponseLoop"
}]