Jump to content




Returning A Custom Error Message


  • You cannot reply to this topic
14 replies to this topic

#1 campicus

  • Members
  • 164 posts

Posted 16 October 2013 - 10:08 PM

Hello geniuses!

Lets say I have a table:
args = {[1]="1",[2]="right",[3]="left",}

What I want to do is return an error message when [1] is not a number. I already get an error message if [1] is not a number:
attempt to perform arithmetic __div on nil and number

however I want the error to return a different error message (which looks a bit neater).

Is this possible?

#2 LBPHacker

  • Members
  • 766 posts
  • LocationBudapest, Hungary

Posted 16 October 2013 - 11:32 PM

Yup, totally
error("something bad happened here")
Cutomize that string up there. If this is a common function of sorts, you can call error so the line number won't point to this function but to the one that called it:
error("wasn't me", 2)


#3 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 16 October 2013 - 11:47 PM

As LBPHacker said it is possible. To expand on his second code example you can also provide a level of 0 to have it not print the filename or line number, only the message.

Here is a tutorial I wrote about errors, error handling and custom errors.

It should be noted that custom errors should not be a replacement for writing code correctly, in the example you've provided, this is a time you shouldn't do it, you should detect whether it's a number and then error if it's not, not wait for Lua to error and then format the message. An example would be
function someApiFunction(num)
  if type(num) ~= "number" then
    error("Expected number for arg #1, got "..type(num), 2) --# to understand what the 2 is for, read my tutorial
  end
end


#4 campicus

  • Members
  • 164 posts

Posted 17 October 2013 - 12:42 AM

Thanks guys. I tried to do what you suggest theoriginalbit:
if type(arg[1]) ~= "number" then
  error("Expected number for arg #1, got "..type(num), 2)
end

however, i think that arg[1] is always a string (as it is defined args = {...}). Then I tried doing this:

if type(tonumber(arg[1])) ~= "number" then
  error("Expected number for arg #1, got "..type(num), 2)
end

but that did not work either. Take a look at my code if you would like clarification.

http://pastebin.com/VgpzHi37

#5 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 17 October 2013 - 01:13 AM

"unknown paste id"

you can however do
if not tonumber(arg[1]) then
  error("Expected number, got "..type(arg[1]), 2)
end

--# it was either a number, or could become a number, so lets make it a number permanently
arg[1] = tonumber(arg[1]) 


#6 campicus

  • Members
  • 164 posts

Posted 17 October 2013 - 08:59 AM

Fixed the link.

That solution does not work for me, it seems like anything can be changed into a number?

#7 ElvishJerricco

  • Members
  • 803 posts

Posted 17 October 2013 - 09:10 AM

View Postcampicus, on 17 October 2013 - 08:59 AM, said:

Fixed the link.

That solution does not work for me, it seems like anything can be changed into a number?

Considering your paste was removed and we don't have enough of your code, it'll be hard to help you. But why store the numbers as strings when you want them as numbers? Do you also need them as strings elsewhere? If that's the case then what bit proposed wouldn't work, since it changes the string to a number permanently. You need to cast between string and number as you see fit. You can either store as one, and use tonumber(args[1]) or tostring(args[1]) when you need it as the other, or you can store it as either and use tonumber and tostring every time you need it so that you're certain you have the right data type.

Of course 99% of the time, if you want to turn a number into a string, Lua will handle that for you. "a" .. 3 is the same as "a3". It'd probably be wise to store the values as numbers because you won't have to worry about casting between data types unless you specifically need args[1] to be a string, without any other manipulation.

#8 campicus

  • Members
  • 164 posts

Posted 17 October 2013 - 09:28 AM

http://pastebin.com/VgpzHi37

Sorry for the confusion guys, hopefully this link works.

I use all strings except for tArgs[1], which needs to be numerical. I have commented out the code that does not function (in the pastebin link) and provided an explanation of what goes wrong.
The code as is works, it just doesn't throw the errors I want it to if the user inputs incorrect parameters.

As always, your help is appreciated

EDIT: I should mention I am using CCDesk to test my code, hopefully it isn't an issue with that :s

#9 TheOddByte

    Lazy Coder

  • Members
  • 1,607 posts
  • LocationSweden

Posted 17 October 2013 - 10:04 AM

Well.. Have you tested it in regular MC, It can still be some bugs in CCDesk and I just tested it and it seemed to work fine..( I tested it with CCEmu )

#10 campicus

  • Members
  • 164 posts

Posted 17 October 2013 - 05:57 PM

It hasn't been possible for me to test it on minecraft unfortunately :(

So if you entered something like:
pulser right left 1
it threw the correct error message ("Pulse interval must be numerical")?

The program itself works fine (the pulsing part). Where I run into issues is when the user enters something like "pulser left right", my custom error message wont pick up that "left" is not a number. These are the two parts of code that are not working (and are commented out in that pastebin link):

if not tonumber(tArgs[1]) then
    print("Pulse interval must be numerical.")
    error("Usage: <pulse interval> <side1> <side2>...", 0)
end
^That code should let me know when the first argument is not a number but it doesn't.

for i,v in ipairs(tArgs) do
    if i > 1 then
        if tArgs[i] ~= ("left" or "right" or "top" or "bottom" or "front" or "back") then
            error("Side must be top, bottom, left, right, back or front", 0) 
        end
    end
end
That code should let me know if tArgs[2] and above are not a valid side, this also does not work.

If you are saying that you ran my code in minecraft, with those bits of code being called (as currently they are not called, they are comments), and it worked, well then that is good, I shall test it in minecraft tonight/tomorrow.

#11 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 17 October 2013 - 11:55 PM

View Postcampicus, on 17 October 2013 - 05:57 PM, said:

if not tonumber(tArgs[1]) then
	print("Pulse interval must be numerical.")
	error("Usage: <pulse interval> <side1> <side2>...", 0)
end
That should work fine, if you want you can put newlines in error messages
if not tonumber(tArgs[1]) then
  error("Pulse interval must be numerical.\nUsage: <pulse interval> <side1> <side2> ...", 0)
end

View Postcampicus, on 17 October 2013 - 05:57 PM, said:

for i,v in ipairs(tArgs) do
	if i > 1 then
		if tArgs[i] ~= ("left" or "right" or "top" or "bottom" or "front" or "back") then
			error("Side must be top, bottom, left, right, back or front", 0)
		end
	end
end
This would not work, and you immediately need to get yourself out of this habit. The section
("left" or "right" or "top" or "bottom" or "front" or "back")
does not work how you think it does, what it does it it resolves all the values, and in Lua a non-nil or non-false will resolve to true, so the statement would end up looking like so
if tArgs[i] ~= (true or true or true or true or true or true) then
now with Boolean OR logic we can see that all those true's resolve down to a single true
true OR true = true
true OR false = true
false OR true = true
false OR false = false
Once Lua has resolved them (since you places brackets around them, it will now compare against tArgs[1]. Resulting in the if statement
if tArgs[i] ~= true then
causing it to error as tArgs[i] will not be true

There are two ways you can do what you wish to do...

#1
if tArgs[i] ~= "left" and tArgs[i] ~= "right" and tArgs[i] ~= "top" and tArgs[i] ~= "bottom" and tArgs[i] ~= "back" and tArgs[i] ~= "back" then
Note we use and here, since we want it to error if all of them don't match.
Boolean AND logic
true AND true = true
true AND false = false
false AND true = false
false AND false = false

#2
The other way, is we can setup a lookup table and check against it like so
local validSides = {
  left = true, --# note it can be any value here except false or nil, it doesn't need to be true
  right = true,
  top = true,
  bottom = true,
  front = true,
  back = true,
}

--# the later when validating
if not validSides[tArgs[i]] then
  error("Not a valid side", 0)
end


#12 campicus

  • Members
  • 164 posts

Posted 18 October 2013 - 05:25 AM

Everything seems to be working now :) Not only that, I know lots more about programming :D

If you're ever in Adelaide, Australia TheOriginalBIT, I owe you a beer.

#13 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 18 October 2013 - 05:28 AM

That's good.

Haha. well I'm not that far away, I'm in Melbourne :P

#14 campicus

  • Members
  • 164 posts

Posted 19 October 2013 - 08:37 AM

View Posttheoriginalbit, on 17 October 2013 - 11:55 PM, said:

#2
The other way, is we can setup a lookup table and check against it like so
local validSides = {
  left = true, --# note it can be any value here except false or nil, it doesn't need to be true
  right = true,
  top = true,
  bottom = true,
  front = true,
  back = true,
}

--# the later when validating
if not validSides[tArgs[i]] then
  error("Not a valid side", 0)
end

Apparently it does need to be true haha

You're an Aussie too!! :D

#15 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 19 October 2013 - 08:48 AM

View Postcampicus, on 19 October 2013 - 08:37 AM, said:

Apparently it does need to be true haha
Nope not at all, in Lua nil and false resolve to false, any other value resolves to true.

If you still don't believe me, here is an image for you. http://puu.sh/4TUFq.png





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users