Posted 19 October 2013 - 01:59 AM
Firstly, ugh sometimes I hate patterns. I'm still not the best I can be with patterns, there are much better people out there, so I've come to you all for help.
Problem
Ok so I'm currently writing a game, and I've got a function, lets call it validate, that can validate supplied values and invokes error when said values are incorrect. The problem I'm facing at the moment is that this validate function can be called from any level, but I want to blame to still be pointed to the original caller.
For example I've got a "class" tree, and lets say class x calls class y as it "extends" it, and class y throws and error because the data supplied to it by x, which is supplied by another function is wrong, the blame needs to be pointed at the function that calls x, not x which is how it currently stands, as such one specific level cannot be supplied for the error/assert function.
Problem Solution
So in order to fix this problem I've created a function that I call, called tryCatch which is the following
Problem w/ Solution
The above solution works fine, however for the messages to be displayed nicely when raising an error anywhere I have to use a level of 0, otherwise the error string is polluted with for example "pcall: <<message>>", this is not ideal, I cannot assume that a level of 0 will always be used due to some of the functions that need to be called with the tryCatch function, I also plan on making this function available to anyone else wishing to add extra modules/content to the game.
As such I need to parse the error message that comes back from the pcall, so that no matter the level, the error message will be all that is raised again. This is where I'm running into problems. The error messages themselves can be a range of formats throughout, here are some examples of format (note, these are not my actual error messages)
Attempts to Solve Solution Problem
Here are my attempts at message parsing
#1 removes the ": " from the message
#3 outputs "you will fear me!"
#4 outputs "fail.png"
#1 outputs nothing
#3 outputs pcall line number
#4 outputs nothing
#1 outputs "you dun-derped"
#3 outputs "fear me"
#4 outputs "fail.png"
#3 outputs "<<pcall line numer>>: Fail: you will always: fail: fear me!"
#4 outputs "fail.png" … again not overly concerned about this oneThat is about all that I know how to do, like I stated, my knowledge in patterns isn't that great, but as you can see the last attempt is the closest I've got, I just cannot seem to get it to work for the third case, I don't really care about #4 it'd be great to have it supported, but I know it'll just be an edge case that get's handled wrong.
Hopefully what I've said makes sense, and you can understand my problem. Maybe you can see another way that I can handle the original problem instead of using tryCatch (do note however, it has to assume dumb users, and not require a throwback level argument). Any help is greatly appreciated.
— BIT
Problem
Ok so I'm currently writing a game, and I've got a function, lets call it validate, that can validate supplied values and invokes error when said values are incorrect. The problem I'm facing at the moment is that this validate function can be called from any level, but I want to blame to still be pointed to the original caller.
For example I've got a "class" tree, and lets say class x calls class y as it "extends" it, and class y throws and error because the data supplied to it by x, which is supplied by another function is wrong, the blame needs to be pointed at the function that calls x, not x which is how it currently stands, as such one specific level cannot be supplied for the error/assert function.
Problem Solution
So in order to fix this problem I've created a function that I call, called tryCatch which is the following
function tryCatch(func, ...)
local ok, err = pcall(func, ...)
if not ok then
error(err, 3)
end
return err
end
Problem w/ Solution
The above solution works fine, however for the messages to be displayed nicely when raising an error anywhere I have to use a level of 0, otherwise the error string is polluted with for example "pcall: <<message>>", this is not ideal, I cannot assume that a level of 0 will always be used due to some of the functions that need to be called with the tryCatch function, I also plan on making this function available to anyone else wishing to add extra modules/content to the game.
As such I need to parse the error message that comes back from the pcall, so that no matter the level, the error message will be all that is raised again. This is where I'm running into problems. The error messages themselves can be a range of formats throughout, here are some examples of format (note, these are not my actual error messages)
1. error("Invalid arg #1: you dun-derped", 2) --# example output... test:5: Invalid arg #1: you dun-derped
2. error("Not initialised", 0) --# example output... Not initialised
3. error("Fail: you will always: fail: fear me!", 3) --# example output... test:7: Fail: you will always: fail: fear me!
4. error("Nope: fail.png", 0) --# P.S. I know this one will be impossible, it's not important if this is handled correctly... example output... Nope: fail.png
Attempts to Solve Solution Problem
Here are my attempts at message parsing
Spoiler
err:gsub("%w+: ?", "")
Fails on:#1 removes the ": " from the message
#3 outputs "you will fear me!"
#4 outputs "fail.png"
err:match("%w+:(/>/>/>/>%w+):")
Fails on:#1 outputs nothing
#3 outputs pcall line number
#4 outputs nothing
err:reverse():match("(.-) ?:%w+"):reverse()
Fails on:#1 outputs "you dun-derped"
#3 outputs "fear me"
#4 outputs "fail.png"
err:match("^%a+:?%d?: ?(.+)")
Fails on:#3 outputs "<<pcall line numer>>: Fail: you will always: fail: fear me!"
#4 outputs "fail.png" … again not overly concerned about this one
Hopefully what I've said makes sense, and you can understand my problem. Maybe you can see another way that I can handle the original problem instead of using tryCatch (do note however, it has to assume dumb users, and not require a throwback level argument). Any help is greatly appreciated.
— BIT