Forum Topic: As: Try And Catch (error Handling)

(2,011 views • 20 replies)

This topic is 1 page long.

<< < > >>
None

authorblues

Reply To Post Reply & Quote

Posted at: 12/25/05 02:46 PM

authorblues FAB LEVEL 12

Sign-Up: 06/21/05

Posts: 6,360

AS: MAIN - dont forget to put it on your christmas list

TRY - CATCH - FINALLY
this is a method of error handling that many of you may not be familiar with. there really is no other necessary knowledge to understand this, except a bit of understanding of classes and conditionals. for all of that, you can look on the AS: MAIN list.

recommended reading
AS: Loops & Conditions by BleeBlap
AS: OOP (Object Oriented Programming) by Inglor
for a bit of background in classes

BASIC TRY/CATCH SETUP
var myNum:Number = null;
try {
if (myNum==null){
throw new Error();
}
}
catch (errorObj:Error){
// put error handling here
}

it should be noted that the try method stops processing when an error is thrown and goes directly to the catch method. now, when you use the try method, it is assumed that it will be followed with the catch method, where you attempt to "throw" an error, that will be "caught" by the catch method. the catch method demands a parameter called the error object. this is used to parse the thrown error. here is a version of the same code, enhanced a bit:

INTERMEDIATE TRY/CATCH SETUP
var myNum:Number = null;
try {
if (myNum==null){
throw new Error("Undefined Variable");
}
}
catch (errorObj:Error){
trace("Unexpected Error: "+errorObj.message);
}

if you didnt follow that code, the output panel will trace "Unexpected Error: Undefined Variable". this is because we threw the error to the catch method, where it parsed it. the error constructor creates a property called "message", where you can create custom errors. you could also try something like throwing different errors with different messages, to intercept special error types. an even better way of intercepting different error types is by extending the error class.

var myNum:Number = Math.round(Math.random());
try {
if (myVar){
throw new TrueVariable();
} else {
throw new FalseVariable();
}
}
catch (errorObj:TrueVariable){
trace("myVar = 1");
}
catch (errorObj:FalseVariable){
trace("myVar = 0");
}

now, we did not properly extend the error class, but the throw method will treat the TrueVariable and the FalseVariable as extensions of the error class, and it will catch in two different ways. the catch with a datatype TrueVariable will only be called if the TrueVariable error is thrown, and a similar thing goes for the FalseVariable error.

ADVANCED TRY/CATCH SETUP
var myWidth:Number = Math.round(Math.random()*25)-5;
var myHeight:Number = Math.round(Math.random()*25)-5;
if (myWidth==0){ myWidth=null };
if (myHeight==0){ myHeight=null };
try {
if (myWidth<=0 || myHeight<=0){
throw new BadDimensions();
} else if (myWidth==undefined || myHeight==undefined){
throw new UndefinedDimensions();
}
_root.createEmptyMovieClip("box", _root.getNextHighestDepth());
with (_root["box"]){
lineStyle(2, 0, 100);
moveTo(0, 0);
lineTo(0, myWidth);
lineTo(myHeight, myWidth);
lineTo(myHeight, 0);
lineTo(0, 0);
}
}
catch (errorObj:BadDimensions){
trace("one of the dimensions of your object are out of range");
}
catch (errorObj:UndefinedDimensions){
trace("one of the dimensions of your object are undefined");
}

this example is a bit large, but two variables are defined randomly between -5 and 25. (i had it change the zeroes to null, just to make this example). if either of the dimensions are undefined (null), it throws an error UndefinedDimensions, which traces an error message. if either of the dimensions are negative, it throws an error BadDimensions, which traces an error message.

FINALLY
this is an optional method, but it runs after the try and catch. you set it up with no parameters, and it is just a way to make sure you run something after the try is completed. usually, this is unneccesary, since whatever is put in the finally block could just as well be put after the whole try/catch routine, but there are some useful methods, such as creating a try/catch/finally routine in a function.

function testFunction():Void {
try {
throw new Error();
}
catch (errObject:Error) {
trace("catch");
return;
}
finally {
trace("finally");
}
}

that will output "catch", and then "finally", despite the fact that the catch block should have aborted the function. other than this, i cant see a reason why the finally couldnt be completely omitted.

that is about it for the try/catch. most of these methods could be combined with OOP to create a more efficient class, but overall, you could possibly achieve the same outcome by just creating a few conditionals. these methods and routines are mostly an issue of readability. they allow you to set up your own error handling system.

SOME PROBLEMS THAT SHOULD BE NOTED:
unfortunately, you cannot make actionscript throw real errors (such as using loadMovieNum or loadMovie in a try block to check for if a file exists). this means that any error handling you do, you must set up for yourself.

that wasnt too long. hope i didnt forget something.

GENERATION 1-i: The first time you see this, copy it into your sig on any forum. Square it, and then add i to the generation.

BBS Signature

None

GuyWithHisComp

Reply To Post Reply & Quote

Posted at: 12/25/05 02:49 PM

GuyWithHisComp LIGHT LEVEL 27

Sign-Up: 11/10/05

Posts: 4,010

Neat tutorial.
May come in handy, suppose you got this from your as book, eh? ;)

BBS Signature

None

authorblues

Reply To Post Reply & Quote

Posted at: 12/25/05 02:53 PM

authorblues FAB LEVEL 12

Sign-Up: 06/21/05

Posts: 6,360

At 12/25/05 02:49 PM, -Snail- wrote: Neat tutorial.
May come in handy, suppose you got this from your as book, eh? ;)

mostly, but i wrote most of the examples by hand
(except the most basic ones - the function and the first one)

GENERATION 1-i: The first time you see this, copy it into your sig on any forum. Square it, and then add i to the generation.

BBS Signature

None

Fire

Reply To Post Reply & Quote

Posted at: 12/25/05 02:54 PM

Fire DARK LEVEL 15

Sign-Up: 10/29/03

Posts: 2,935

So this is useful if, say, you were making a program that pluralizes words, and you put the catch(); function right before the script to check for words that cant be pluralized.


None

authorblues

Reply To Post Reply & Quote

Posted at: 12/25/05 02:57 PM

authorblues FAB LEVEL 12

Sign-Up: 06/21/05

Posts: 6,360

At 12/25/05 02:54 PM, GameCubeFreak2004 wrote: So this is useful if, say, you were making a program that pluralizes words, and you put the catch(); function right before the script to check for words that cant be pluralized.

that wouldnt be a great use for it, but theoretically, that is a use.
its mostly for testing for user-input for certain restrictions...

GENERATION 1-i: The first time you see this, copy it into your sig on any forum. Square it, and then add i to the generation.

BBS Signature

None

Fire

Reply To Post Reply & Quote

Posted at: 12/25/05 02:58 PM

Fire DARK LEVEL 15

Sign-Up: 10/29/03

Posts: 2,935

I see.


None

GuyWithHisComp

Reply To Post Reply & Quote

Posted at: 12/25/05 03:05 PM

GuyWithHisComp LIGHT LEVEL 27

Sign-Up: 11/10/05

Posts: 4,010

Wait shouldn't this:

At 12/25/05 02:46 PM, authorblues wrote: var myNum:Number = Math.round(Math.random());
try {
if (myVar){

be

var myNum:Number = Math.round(Math.random());
try {
if (myNum){

?? :O

BBS Signature

None

authorblues

Reply To Post Reply & Quote

Posted at: 12/25/05 03:11 PM

authorblues FAB LEVEL 12

Sign-Up: 06/21/05

Posts: 6,360

At 12/25/05 03:05 PM, -Snail- wrote: Wait shouldn't this: be ?? :O

yeah, sorry. typed it quickly.

GENERATION 1-i: The first time you see this, copy it into your sig on any forum. Square it, and then add i to the generation.

BBS Signature

None

FrostedMuffins

Reply To Post Reply & Quote

Posted at: 12/25/05 06:45 PM

FrostedMuffins LIGHT LEVEL 29

Sign-Up: 11/03/04

Posts: 1,164

Awesome tutorial Authorblues! This is EXTREMELY useful and I'll try to get more into it later once I've gotten a better grasp of classes. Thanks a lot for taking the time to create this.


None

GuyWithHisComp

Reply To Post Reply & Quote

Posted at: 12/26/05 05:55 AM

GuyWithHisComp LIGHT LEVEL 27

Sign-Up: 11/10/05

Posts: 4,010

Can this be used like if you're using getURL and the website doesn't exist?
Like
var myVar:String = "http://www.linky.com/";
try {
if (myVar==undefined){
throw new Error();
}
}
trace("Website didn't exist!");
}

Or something...

BBS Signature

None

Thomas

Reply To Post Reply & Quote

Posted at: 12/26/05 06:01 AM

Thomas LIGHT LEVEL 13

Sign-Up: 02/14/05

Posts: 2,833

Nice tutorial.

BTW,this is a completely off-topic comment,but -Snail-,I think you need to slow down.

You have 814 posts and you've only been here for a month =P


None

liaaaam

Reply To Post Reply & Quote

Posted at: 1/1/06 02:47 PM

liaaaam NEUTRAL LEVEL 22

Sign-Up: 12/11/04

Posts: 14,536

Neat tutorial, but with the BadDimensions thing (And the other ones) it gives this error:

**Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 21: The class or interface 'BadDimensions' could not be loaded.
catch (errorObj:BadDimensions){

because BadDimensions isn't a Class, so wouldn't it be better doing it like this:

var myWidth:Number = Math.round(Math.random()*25)-5;
var myHeight:Number = Math.round(Math.random()*25)-5;
if (myWidth == 0) {
myWidth = null;
}
if (myHeight == 0) {
myHeight = null;
}
try {
if (myWidth<=0 || myHeight<=0) {
throw new Error("BadDimensions");
} else if (myWidth == undefined || myHeight == undefined) {
throw new Error("UndefinedDimensions");
}
_root.createEmptyMovieClip("box", _root.getNextHighestDepth());
with (_root["box"]) {
lineStyle(2, 0, 100);
moveTo(0, 0);
lineTo(0, myWidth);
lineTo(myHeight, myWidth);
lineTo(myHeight, 0);
lineTo(0, 0);
}
} catch (errorObj:Error) {
if (errorObj.message == "BadDimensions") {
trace("One of the dimensions are out of range");
} else if (errorObj.message == "UndefinedDimensions") {
trace("One of the dimensions are undefined");
}
}

At 12/26/05 05:55 AM, -Snail- wrote: Can this be used like if you're using getURL and the website doesn't exist?

No that wouldn't work, because it's checking the var not the url.. you can't check if the URL exists through Flash.

At 12/26/05 06:01 AM, -Thomas wrote: BTW,this is a completely off-topic comment,but -Snail-,I think you need to slow down.
You have 814 posts and you've only been here for a month =P

15 posts a day is just WEAK.


None

UnknownFury

Reply To Post Reply & Quote

Posted at: 1/1/06 02:59 PM

UnknownFury EVIL LEVEL 26

Sign-Up: 08/10/05

Posts: 6,031

Nice and clear tut dude!
I have seen alot of you latly you are starting to become my favorite bbs user :D
Keep up the good work

Portfolio(Under construction): UnknownFury.com |
Msn: giant_ak_47@msn.com | Contact: me@unknownfury.com
Follow me on twitter!


None

Rammer

Reply To Post Reply & Quote

Posted at: 1/1/06 03:05 PM

Rammer DARK LEVEL 32

Sign-Up: 06/08/03

Posts: 4,331

At 1/1/06 02:59 PM, -bloodskater- wrote: Nice and clear tut dude!
I have seen alot of you latly you are starting to become my favorite bbs user :D
Keep up the good work

suck-up.

but i have been waiting for someone to make this tutorial. i never really understood try..catch..finally, but your tutorial clarified some of it.

snyggys


None

authorblues

Reply To Post Reply & Quote

Posted at: 1/1/06 03:11 PM

authorblues FAB LEVEL 12

Sign-Up: 06/21/05

Posts: 6,360

At 1/1/06 02:47 PM, -liam- wrote: Neat tutorial, but with the BadDimensions thing (And the other ones) it gives this error:

i was fairly certian that when i looked it up, it said that the throw method would automatically extend the error class to whatever class you told it to throw. i guess i was wrong, thank you for pointing that out. and yes, your version would work fine...

GENERATION 1-i: The first time you see this, copy it into your sig on any forum. Square it, and then add i to the generation.

BBS Signature

None

Rammer

Reply To Post Reply & Quote

Posted at: 1/1/06 03:15 PM

Rammer DARK LEVEL 32

Sign-Up: 06/08/03

Posts: 4,331

At 1/1/06 03:11 PM, authorblues wrote:
i was fairly certian that when i looked it up, it said that the throw method would automatically extend the error class to whatever class you told it to throw. i guess i was wrong, thank you for pointing that out. and yes, your version would work fine...

happy almost-2,100-posts, authorblues! :P

snyggys


None

Alphabit

Reply To Post Reply & Quote

Posted at: 2/9/07 07:32 AM

Alphabit NEUTRAL LEVEL 09

Sign-Up: 02/14/06

Posts: 4,060

I never saw a point for error handling of this type... Could someone explain the actual purpose...
personally, I think that's flash's automatic error-handling works well enough for me.
... Also, I like to test often, so if there is an error in-between testing sessions, then I know where the problem comes from anyway.


None

GustTheASGuy

Reply To Post Reply & Quote

Posted at: 2/9/07 08:09 AM

GustTheASGuy LIGHT LEVEL 08

Sign-Up: 11/02/05

Posts: 11,377

Well, as you may know AS1-2 almost always doesn't give any sign of anything being wrong, but AS3 throws errors all around on the contrary. Doesn't that help you? Because it sucks having a lengthy code of handling maths and whatnot and it just doesn't put anything out and you have to spend an hour putting tracing statements all over the place. Also error handling is a way of flow control, because it skips everything until it is catched.

#ngprogramming at irc.freenode.net
haXe | Keel imperative | Spyro! | Thru you


None

Alphabit

Reply To Post Reply & Quote

Posted at: 2/9/07 08:19 AM

Alphabit NEUTRAL LEVEL 09

Sign-Up: 02/14/06

Posts: 4,060

At 2/9/07 08:09 AM, OldGust wrote: Well, as you may know AS1-2 almost always doesn't give any sign of anything being wrong, but AS3 throws errors all around on the contrary. Doesn't that help you? Because it sucks having a lengthy code of handling maths and whatnot and it just doesn't put anything out and you have to spend an hour putting tracing statements all over the place. Also error handling is a way of flow control, because it skips everything until it is catched.

Nicely explained thanks.
Personally, I don't mind that the code stops executing when an error is encountered... In fact I don't mind solving one problem after another. Hehe, I like using trace() to output the state of objects... That way if the object/array/whatever isn't what I want it to be, then I know there is a problem associated with the object itself... Then it's easy to find the error.


None

LeechmasterB

Reply To Post Reply & Quote

Posted at: 2/9/07 10:30 AM

LeechmasterB EVIL LEVEL 16

Sign-Up: 04/01/05

Posts: 934

Well think about what you could use the finally for... :). Like when you have a function that returns something or sometimes not (whatever) and you want something to always be done without having to add it before every return statement. Check out the two examples and you should get the idea:

[code a: without finally]
function tryCatch():Number {
var rand:Number = random(3);
try {
if (rand == 1) {
trace("case 1");
throw new Error("OMG ITS 1!");
trace("this stuff will always be called but had to be written several times");
return 1;
} else if (rand == 2) {
trace("case 2");
throw new Error("OMG ITS 2!");
trace("this stuff will always be called but had to be written several times");
return 2;
} else {
trace("default");
throw new Error();
trace("this stuff will always be called but had to be written several times");
return null;
}
} catch (errorObj:Error) {
trace("errorObj.message: "+errorObj.message);
switch (errorObj.message) {
case "OMG ITS 1!" :
trace("it is 1..");
break;
case "OMG ITS 2!" :
trace("it is 2..");
break;
default :
trace("unexpected error occured!");
break;
}
return;
}
trace("this stuff here doesn't really get a chance to be called");
}
_root.onEnterFrame = function():Void {
trace("calling: "+_root.tryCatch());
};

[/code a]

Now instead of having to output the same stuff several times before the returning just use a finally and save work ect. (this is an example think in bigger code dimensions for it to make really sense). ---

[code b: with finally]
function tryCatch():Number {
var rand:Number = random(3);
try {
if (rand == 1) {
trace("case 1");
throw new Error("OMG ITS 1!");
return 1;
} else if (rand == 2) {
trace("case 2");
throw new Error("OMG ITS 2!");
return 2;
} else {
trace("default");
throw new Error();
return null;
}
} catch (errorObj:Error) {
trace("errorObj.message: "+errorObj.message);
switch (errorObj.message) {
case "OMG ITS 1!" :
trace("it is 1..");
break;
case "OMG ITS 2!" :
trace("it is 2..");
break;
default :
trace("unexpected error occured!");
break;
}
return;
} finally {
trace("this stuff will always be called");
}
trace("this stuff here doesn't really get a chance to be called");
}
_root.onEnterFrame = function():Void {
trace("calling: "+_root.tryCatch());
};

[/code b]

I hope that cleared it up for ya guys :).


None

LeechmasterB

Reply To Post Reply & Quote

Posted at: 2/9/07 11:53 AM

LeechmasterB EVIL LEVEL 16

Sign-Up: 04/01/05

Posts: 934

Yeah actually the first "bad" example should be changed a bit like this to make it show:

[code a: without finally]
function tryCatch():Number {
var rand:Number = random(3);
try {
if (rand == 1) {
trace("case 1");
trace("this stuff will always be called but had to be written several times");
throw new Error("OMG ITS 1!");
return 1;
} else if (rand == 2) {
trace("case 2");
trace("this stuff will always be called but had to be written several times");
throw new Error("OMG ITS 2!");
return 2;
} else {
trace("default");
trace("this stuff will always be called but had to be written several times");
throw new Error();
return null;
}
} catch (errorObj:Error) {
trace("errorObj.message: "+errorObj.message);
switch (errorObj.message) {
case "OMG ITS 1!" :
trace("it is 1..");
break;
case "OMG ITS 2!" :
trace("it is 2..");
break;
default :
trace("unexpected error occured!");
break;
}
return;
}
trace("this stuff here doesn't really get a chance to be called");
}
_root.onEnterFrame = function():Void {
trace("calling: "+_root.tryCatch());
};

[/code a]

Now instead of having to output the same stuff several times before the returning just use a finally and save work ect. (this is an example think in bigger code dimensions for it to make really sense). ---

[code b: with finally]
function tryCatch():Number {
var rand:Number = random(3);
try {
if (rand == 1) {
trace("case 1");
throw new Error("OMG ITS 1!");
return 1;
} else if (rand == 2) {
trace("case 2");
throw new Error("OMG ITS 2!");
return 2;
} else {
trace("default");
throw new Error();
return null;
}
} catch (errorObj:Error) {
trace("errorObj.message: "+errorObj.message);
switch (errorObj.message) {
case "OMG ITS 1!" :
trace("it is 1..");
break;
case "OMG ITS 2!" :
trace("it is 2..");
break;
default :
trace("unexpected error occured!");
break;
}
return;
} finally {
trace("this stuff will always be called");
}
trace("this stuff here doesn't really get a chance to be called");
}
_root.onEnterFrame = function():Void {
trace("calling: "+_root.tryCatch());
};

[/code b]

But still this is just if you inist on testing the source ^^


All times are Eastern Standard Time (GMT -5) | Current Time: 09:32 PM

<< Back

This topic is 1 page long.

<< < > >>
You need a Grounds Gold Account to post on the NG BBS! If you don't have one, click here to sign up now! It's fast, free, and easy — and opens up tons of great NG features!