A die(reason) or exit function is missing, isn't it?

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

A die(reason) or exit function is missing, isn't it?

DracoBlue
Hello,

I already talked with brianm about the mod_lua/wombat project and a die(reason)-function, but I think this is a general question, which maybe discussed not only in the irc.

Since there is a os.exit function, which (in mod_lua) kills the apache2 - I was searching for a way to finish scriptexecution somewhere in the script. In PHP there is a function called http://php.net/die - have a look there for details.

Why is this needed? I am using several database and templating connections, but if there is any issues (in 4th, 5th (or more) recusion step) its not possible to stop execution with with if-else-constructs. So a die("Error occured") would be greatly appriciated.

Kind regards,
 Jan (DracoBlue)
------------------------
   http://dracoblue.net


Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

Alex Queiroz
Hallo,

On 1/25/07, Jan Schütze <[hidden email]> wrote:

Why is this needed? I am using several database and templating
connections, but if there is any issues (in 4th, 5th (or more) recusion
step) its not possible to stop execution with with if-else-constructs.
So a die("Error occured") would be greatly appriciated.


    What about raising an error?

--
-alex
http://www.ventonegro.org/


Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

Gergo Szakal
In reply to this post by DracoBlue
On Thu, 25 Jan 2007 20:38:38 +0100
Jan Schütze <[hidden email]> wrote:

error()
assert()


-- 
Gergo Szakal <[hidden email]>



Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

DracoBlue
In reply to this post by Alex Queiroz
Hello Alex,

This isn't only used to report an error to users on website.
Since I use lua for webpublishing, I have somewher ein my source a function called xml_render() - this one, should use die at the end, to prevent from showing header and stuff when the rest of the script is executed. The issue is, that this function is called mostly somewhere in a set of sets of function-sets, so its not possible (easily, without making the source unreadable) to do this via using if-else-constructs.

Kind regards,
 Jan (DracoBlue)
--------------------------
   http://dracoblue.net

Alex Queiroz schrieb:
Hallo,

On 1/25/07, Jan Schütze <[hidden email]> wrote:

Why is this needed? I am using several database and templating
connections, but if there is any issues (in 4th, 5th (or more) recusion
step) its not possible to stop execution with with if-else-constructs.
So a die("Error occured") would be greatly appriciated.


    What about raising an error?


Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

Alex Queiroz
Hallo,

On 1/25/07, Jan Schütze <[hidden email]> wrote:

This isn't only used to report an error to users on website.
Since I use lua for webpublishing, I have somewher ein my source a
function called xml_render() - this one, should use die at the end, to
prevent from showing header and stuff when the rest of the script is
executed. The issue is, that this function is called mostly somewhere in
a set of sets of function-sets, so its not possible (easily, without
making the source unreadable) to do this via using if-else-constructs.


    You can catch the error before it reaches the user with pcall().

--
-alex
http://www.ventonegro.org/


Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

Romulo Bahiense
Alex Queiroz wrote:
Hallo,

On 1/25/07, Jan Schütze <[hidden email]> wrote:

This isn't only used to report an error to users on website.
Since I use lua for webpublishing, I have somewher ein my source a
function called xml_render() - this one, should use die at the end, to
prevent from showing header and stuff when the rest of the script is
executed. The issue is, that this function is called mostly somewhere in
a set of sets of function-sets, so its not possible (easily, without
making the source unreadable) to do this via using if-else-constructs.


    You can catch the error before it reaches the user with pcall().


I myself use a function abort(), which is something like:

local _die = {}
function abort() error(_die) end

And to catch it (pseudo code):


local handler = gethandlerforrequest( url )
local ok, err = pcall( handler )

if not ok and err ~= _die then
    -- something bad happened. Log it
    log.error(
        'An error occurred at a random address. ' .. tostring( err )
    )
end


Note that _die isn't visible anywhere else, so no one would be able to mimic abort() behavior.

--rb



Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

DracoBlue
In reply to this post by Alex Queiroz
Hello,

so I should call the mainfunction with pcall and ignore its message this way?
Hmm, should be possible - but looks like an evil hack :-).

Thanks for fast response, hope that lua-devs implement a die, so such workaround isn't needed.

Kind regards,
 Jan (DracoBlue)
-------------------------
   http://dracoblue.net


Alex Queiroz schrieb:
Hallo,

On 1/25/07, Jan Schütze <[hidden email]> wrote:

This isn't only used to report an error to users on website.
Since I use lua for webpublishing, I have somewher ein my source a
function called xml_render() - this one, should use die at the end, to
prevent from showing header and stuff when the rest of the script is
executed. The issue is, that this function is called mostly somewhere in
a set of sets of function-sets, so its not possible (easily, without
making the source unreadable) to do this via using if-else-constructs.


    You can catch the error before it reaches the user with pcall().


Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

Rici Lake-2
In reply to this post by Alex Queiroz

On 25-Jan-07, at 3:01 PM, Alex Queiroz wrote:

Hallo,

On 1/25/07, Jan Schütze <[hidden email]> wrote:

This isn't only used to report an error to users on website.
Since I use lua for webpublishing, I have somewher ein my source a
function called xml_render() - this one, should use die at the end, to
prevent from showing header and stuff when the rest of the script is
executed. The issue is, that this function is called mostly somewhere in
a set of sets of function-sets, so its not possible (easily, without
making the source unreadable) to do this via using if-else-constructs.


    You can catch the error before it reaches the user with pcall().


Another simple solution is to make the outermost function a coroutine and define exit = coroutine.yield



Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

DracoBlue
Thanks for all good responses.

Kind regards,
 Jan (DracoBlue)
--------------------------
   http://dracoblue.net

Reply | Threaded
Open this post in threaded view
|

RE: A die(reason) or exit function is missing, isn't it?

Jerome Vuarand-2
In reply to this post by DracoBlue
Jan Schütze wrote:
> so I should call the mainfunction with pcall and ignore its 
> message this way?
> Hmm, should be possible - but looks like an evil hack :-).

In fact it's not an evil hack, it's the way error management works in Lua. It's similar to exceptions in C++. Whether Lua errors or C++ exceptions are a good way to report errors is a religious debate, but in both case it's a reliable, well defined and powerful mechanism. Whether you use it or abuse it is up to you.


Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

DracoBlue
Correct.
But only for error and exception handling.

I don't need it to handle an failure or an exception, its normal case - so there should be a normal function to do this, without such a big (and good working!) workaround, which Romulo posted.

Just posted mainly to help improving lua with what is often needed in developing web. applications. But you are correct, depends on the point of view, and where(/how often) you need such functionality.

Kind regards,
 Jan (DracoBlue)
---------------------------
   http://dracoblue.net

Jerome Vuarand schrieb:
Jan Schütze wrote:
so I should call the mainfunction with pcall and ignore its message this way?
Hmm, should be possible - but looks like an evil hack :-).

In fact it's not an evil hack, it's the way error management works in Lua. It's similar to exceptions in C++. Whether Lua errors or C++ exceptions are a good way to report errors is a religious debate, but in both case it's a reliable, well defined and powerful mechanism. Whether you use it or abuse it is up to you.



Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

Rici Lake-2

On 25-Jan-07, at 5:21 PM, Jan Schütze wrote:

Correct.
But only for error and exception handling.

I don't need it to handle an failure or an exception, its normal case - so there should be a normal function to do this, without such a big (and good working!) workaround, which Romulo posted.

Surely if you call a function "die", you're implying that it's a response to a failure or exceptional condition :) In which case, using an error() based exception system seems entirely appropriate.

If you want to do a "compressed return" from a nested recursion, you should think seriously about coroutines, which make that convenient, as well as being more flexible because they give the option of accepting a result or continuing a search.

For example:

trythis = coroutine.yield

function find()
  for value in some_query(database) do
    find2(database, value)
  end
end

function find2(database, value)
  for value2 in some_other_query(database, value) do
    find3(database, value, value2)
  end
end

function find3(database, v1, v2)
  for result in yet_another_query(database, v1, v2) do
    trythis(result)
  end
end

-- main search

local function search()
  local finder = coroutine.wrap(find)
  local result
  repeat
    result = finder()
    if checks_out(result) then return result end
    until not result
  end
  error "Not found"
end





Just posted mainly to help improving lua with what is often needed in developing web. applications. But you are correct, depends on the point of view, and where(/how often) you need such functionality.



Reply | Threaded
Open this post in threaded view
|

Re: A die(reason) or exit function is missing, isn't it?

DracoBlue
Thanks for Rici Lake for this code snippet. I think I got the point with yield and coreroutines and how to use them.

Seems (for me) to be best soloution for me now, since so I have a main-routine (in my templating system), which can be called as coroutine and will end when its finished or yield. Nice, thanks. Hope this helps others, which have the same issue with current lua version.

Kind regards,
   Jan (DracoBlue)
-------------------------
   http://dracoblue.net


Rici Lake schrieb:

On 25-Jan-07, at 5:21 PM, Jan Schütze wrote:

Correct.
But only for error and exception handling.

I don't need it to handle an failure or an exception, its normal case - so there should be a normal function to do this, without such a big (and good working!) workaround, which Romulo posted.

Surely if you call a function "die", you're implying that it's a response to a failure or exceptional condition :) In which case, using an error() based exception system seems entirely appropriate.

If you want to do a "compressed return" from a nested recursion, you should think seriously about coroutines, which make that convenient, as well as being more flexible because they give the option of accepting a result or continuing a search.

For example:

trythis = coroutine.yield

function find()
  for value in some_query(database) do
    find2(database, value)
  end
end

function find2(database, value)
  for value2 in some_other_query(database, value) do
    find3(database, value, value2)
  end
end

function find3(database, v1, v2)
  for result in yet_another_query(database, v1, v2) do
    trythis(result)
  end
end

-- main search

local function search()
  local finder = coroutine.wrap(find)
  local result
  repeat
    result = finder()
    if checks_out(result) then return result end
    until not result
  end
  error "Not found"
end





Just posted mainly to help improving lua with what is often needed in developing web. applications. But you are correct, depends on the point of view, and where(/how often) you need such functionality.