Page 1 of 1

openURL: How to handle gracefully run time errors

Posted: Wednesday 13 May 2020 11:59
by Number8
Hello,

openURL (async), for whatever reasons (remote server not available for instance) may throw an error message in the Domoticz log which will stop execution.
I have made many try and errors to understand LUA error catching mecanism. It gets more difficult with an async function because the error is not triggered at the time openURL is called.
Event worse the error message transcript in Domoticz log shows account name and password

Code: Select all

http://192.168.21.247:50001/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=2&account=xxxxx&passwd=yyyyyyyyy&session=SurveillanceStation&format=sid 
2020-05-13 11:26:58.610 Error: dzVents: Error: (3.0.4) camera script: HTTP/1.1 response: 7 ==>> Couldn't connect to server 
I'm really scratching my head on how to catch runtime errors to handle them properly. Anybody having ideas?

As a side note, assert is not usable in the context of dzvents. As matter of fact if an error condition arises, the script is stopped rightaway.
Thank you

Re: openURL: How to handle gracefully run time errors

Posted: Wednesday 13 May 2020 15:13
by waaren
Number8 wrote: Wednesday 13 May 2020 11:59 I'm really scratching my head on how to catch runtime errors to handle them properly. Anybody having ideas?
As a side note, assert is not usable in the context of dzvents. As matter of fact if an error condition arises, the script is stopped rightaway.
Lua's assert is meant for error tracking. Not for error handling.

Did you look at pcall / xpcall ?

pcall (f, arg1, ···)
Calls function f with the given arguments in protected mode. This means that any error inside f is not propagated; instead, pcall catches the error and returns a status code. Its first result is the status code (a boolean), which is true if the call succeeds without errors. In such case, pcall also returns all results from the call, after this first result. In case of any error, pcall returns false plus the error message.

xpcall (f, err)
This function is similar to pcall, except that you can set a new error handler.

xpcall calls function f in protected mode, using err as the error handler. Any error inside f is not propagated; instead, xpcall catches the error, calls the err function with the original error object, and returns a status code. Its first result is the status code (a boolean), which is true if the call succeeds without errors. In this case, xpcall also returns all results from the call, after this first result. In case of any error, xpcall returns false plus the result from err.

Re: openURL: How to handle gracefully run time errors

Posted: Wednesday 13 May 2020 16:33
by Number8
Thanks waaren, I had looked at pcall and xpcall. I made a specific test program using pcall to understand how to handle it. The test program does what I expect. However, I understand that the error is triggered not at the openURL stage, but during the callback that I don't know how to protect. I defined an URL that I know it will not answer. So the callback is triggered by some other mecanism I guess (some timeout?). In that case I just don"t see how to catch the error. Any idea? You could tell that I could ping before calling openURL, but this not the idea.

Compared to other languages (Python, C, whatever) error handling is to my point of view cumbersome.

Re: openURL: How to handle gracefully run time errors  [Solved]

Posted: Wednesday 13 May 2020 20:30
by waaren
Number8 wrote: Wednesday 13 May 2020 16:33 In that case I just don"t see how to catch the error. Any idea? You could tell that I could ping before calling openURL, but this not the idea.
You could just catch the statusCode like below.

Code: Select all

local scriptVar = 'faultyJSON'

return 
{
	on = 
	{
		devices = 
		{
			'faultyJSON', -- just a trigger for the script
		},
		httpResponses = 
		{
			scriptVar,
		},
	},
	
	logging =
	{
        level = domoticz.LOG_DEBUG,
    },
    
	execute = function(dz, item)

		if item.isDevice then
			dz.openURL({
				url = 'https://httpstat.us/100', -- this url will not return anything
				callback = scriptVar, -- see httpResponses above.
			})
	    else
	        dz.log(item, dz.LOG_DEBUG)
	        if item.ok then 
	            dz.log('This is really a surprise ', dz.LOG_DEBUG)
	        else
	           dz.log('This is expected. The returncode is ' .. item.statusCode, dz.LOG_DEBUG) -- should take about 90 seconds
	        end
	    end
    end
}

Re: openURL: How to handle gracefully run time errors

Posted: Wednesday 13 May 2020 22:07
by Number8
Thank you waaren, dzvents is definitely full of ressources. I was looking for a too complex solution. This one is really smart. I’ll make the test tomorrow first thing

Re: openURL: How to handle gracefully run time errors

Posted: Thursday 14 May 2020 9:03
by Number8
@waaren this is indeed the right way to handle it. Thanks very much again. However despite the item.ok test, dzVents still logs in red the error message in red published in the OP, that is full url including account and password in this particular case. I let devs decide whatever they think it is best, but to my point of view this message shouldn't be thrown and if it is, the detailed info should be obfuscated.