Author Topic: AutoCAD.NET | Handling *Exceptions  (Read 21636 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8690
  • AKA Daniel
Re: AutoCAD.NET | Handling *Exceptions
« Reply #15 on: April 17, 2012, 08:44:14 PM »
Obviously this must be used in the right environment and with some caution
I use it for "LispFunctions"
Code - C#: [Select]
  1. try {
  2.   //anything
  3. } catch {}
  4.  return null

But this code snippet is present in many more "professional codes" ("commercial" dll's)  than any one could imagine

True,  and it's one of those snippets that gets in your code and you forget about.  IMHO, if you're going to use it, you might want to post out a message on DEBUG builds.  Just to remind you that you have ugly code that can probably be dealt with in a more elegant fashion. 

exmachina

  • Guest
Re: AutoCAD.NET | Handling *Exceptions
« Reply #16 on: April 17, 2012, 08:55:12 PM »
Wow thanks for those great links!!
 
I never have heard of MSDN. I wish I had known about that before.
Oh crap its in English like you mentioned. I can only talk and write in English, but read in Kazakhstaneese.
Oh well.

Therefore I recommend that you read MSDN

I have three hobbies
1. Fishing
2. women
3. programming

It seems that i caught anything, Which will it be?:
cat fish, black bass, walleye or frog?

 :angel: :angel: :angel: :angel:

exmachina

  • Guest
Re: AutoCAD.NET | Handling *Exceptions
« Reply #17 on: April 17, 2012, 09:34:04 PM »
True,  and it's one of those snippets that gets in your code and you forget about.  IMHO, if you're going to use it, you might want to post out a message on DEBUG builds.  Just to remind you that you have ugly code that can probably be dealt with in a more elegant fashion.

I use this to hide a error to the end user. for example: during the execution closes the connection to mysql server, but the user only needs to know if was successful or not.

This can be an eternal discussion: But I think that the two we have felt the same thing on one occasion : "I know it's sometimes hard to avoid but it should be used with caution"

 good night

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AutoCAD.NET | Handling *Exceptions
« Reply #18 on: April 17, 2012, 10:12:34 PM »
<  ... >
I have three hobbies
1. Fishing
2. women
3. programming



I had to laugh about this;
These are the 3 things that most men lie about ( so I'm told)  :-D
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

exmachina

  • Guest
Re: AutoCAD.NET | Handling *Exceptions
« Reply #19 on: April 18, 2012, 01:32:04 AM »
I had to laugh about this;
These are the 3 things that most men lie about ( so I'm told)  :-D
:laugh: :laugh: :laugh: :laugh: :laugh:
You're probably right. But those are my hobbies, although the order of preference does not correspond to the result
1. I am a good fisherman
2. I'm a bad coder/programmer
3. ... Without comments

Good morning to all!

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8690
  • AKA Daniel
Re: AutoCAD.NET | Handling *Exceptions
« Reply #20 on: April 18, 2012, 03:38:57 AM »
I use this to hide a error to the end user. for example: during the execution closes the connection to mysql server, but the user only needs to know if was successful or not.

See the flaw? Why not catch mysql exceptions and let the exceptional continue on its merry way up the stack ?

exmachina

  • Guest
Re: AutoCAD.NET | Handling *Exceptions
« Reply #21 on: April 18, 2012, 05:20:21 AM »
Sorry, but i dont see any fault.  And in addition i think it has a better performance

Look this:

C# code
Code - C#: [Select]
  1. using MySql.Data.MySqlClient;
  2. namespace ClassLibrary1 {
  3.     public class Class1 {
  4.         public void func1() {
  5.             try {
  6.             } catch (Exception ex) { }
  7.         }
  8.         public void func2() {
  9.             try {
  10.             } catch (MySqlException ex) { }
  11.         }
  12.         public void func3() {
  13.             try {
  14.             } catch  { }
  15.         }
  16.     }
  17. }

IL
Code: [Select]
  .method public hidebysig instance void func1() cil managed
    {
        .maxstack 1
        .locals init (
            [0] class [mscorlib]System.Exception ex)
        L_0000: nop
        L_0001: nop
        L_0002: nop
        L_0003: leave.s L_000a
        L_0005: stloc.0
        L_0006: nop
        L_0007: nop
        L_0008: leave.s L_000a
        L_000a: nop
        L_000b: ret
        .try L_0001 to L_0005 catch [mscorlib]System.Exception handler L_0005 to L_000a
    }

    .method public hidebysig instance void func2() cil managed
    {
        .maxstack 1
        .locals init (
            [0] class [MySql.Data]MySql.Data.MySqlClient.MySqlException ex)
        L_0000: nop
        L_0001: nop
        L_0002: nop
        L_0003: leave.s L_000a
        L_0005: stloc.0
        L_0006: nop
        L_0007: nop
        L_0008: leave.s L_000a
        L_000a: nop
        L_000b: ret
        .try L_0001 to L_0005 catch [MySql.Data]MySql.Data.MySqlClient.MySqlException handler L_0005 to L_000a
    }

    .method public hidebysig instance void func3() cil managed
    {
        .maxstack 1
        L_0000: nop
        L_0001: nop
        L_0002: nop
        L_0003: leave.s L_000a
        L_0005: pop
        L_0006: nop
        L_0007: nop
        L_0008: leave.s L_000a
        L_000a: nop
        L_000b: ret
        .try L_0001 to L_0005 catch object handler L_0005 to L_000a
    }


Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AutoCAD.NET | Handling *Exceptions
« Reply #22 on: April 18, 2012, 05:57:37 AM »
exmachina (whoknows)

The purpose of a catch statement is generally to handle an exception
... and it is considered good practice to actually handle an  exception, not to ignore it.

Also, when working with database objects ( or any object that should be disposed or closed)
it is usual practice to use a finally statement.

I believe you know this and may be just making your posts to cause a discussion.
If that is the case, please don't, because learners will read these posts
and leave with the wrong impression.


//===========

Your comment about better performance is really
not relevant if the code is not well behaved.

Regards
Kerry   
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

exmachina

  • Guest
Re: AutoCAD.NET | Handling *Exceptions
« Reply #23 on: April 18, 2012, 06:24:58 AM »
...
I believe you know this and may be just making your posts to cause a discussion.
...

No. And i dont like "discussions". But in any case I apologize if I have bothered or offended someone. I had no intention to offend anyone.


...

Your comment about better performance is really
not relevant if the code is not well behaved.

Regards
Kerry

thinking better :I have reason and also I'm wrong
seems that this code (empty catch) can catch all exceptions, even non-CLS compliant exceptions.
« Last Edit: April 18, 2012, 06:29:52 AM by whoknows »

TheMaster

  • Guest
Re: AutoCAD.NET | Handling *Exceptions
« Reply #24 on: April 18, 2012, 06:48:43 AM »
Quote

I use this to hide a error to the end user. for example: during the execution closes the connection to mysql server, but the user only needs to know if was successful or not.


Of course, you can do whatever you think is correct, but if an error happens
for some reason you didn't expect, then you will never know, and the user
will have no way to tell you what's gone wrong.

The point to catching exceptions is to provide a way to find out if an error
you did not expect happens, and what the error is.

Your ideas seem to be predicated on a presumption that your code could
never fail for reasons you didn't expect.

try{} catch {} is like "On Error Resume Next" in legacy VB/VBA, and you
can find plenty of discussion about what's wrong with the latter if you
do the research.

exmachina

  • Guest
Re: AutoCAD.NET | Handling *Exceptions
« Reply #25 on: April 18, 2012, 07:40:09 AM »
Of course, you can do whatever you think is correct, but if an error happens
for some reason you didn't expect, then you will never know, and the user
will have no way to tell you what's gone wrong.
Is intentional. It is a library that provides functions to AutoLisp

Your ideas seem to be predicated on a presumption that your code could
never fail for reasons you didn't expect.
No. It is just the opposite I really think that my code might fail at anything. THIS IS TRUE.It seems that I'm a bit pessimistic

try{} catch {} is like "On Error Resume Next" in legacy VB/VBA, and you
can find plenty of discussion about what's wrong with the latter if you
do the research.
I think I understand how to use try/catch, but today I discovered that is not the same use an empty catch block that a system.exception.
One year ago I had a problem with SEHException (I could not fix) and today I have just discovered that can be  handled with an empty block!!!!! :ugly:

It is true that I come from the VB world and i had many prroblemas to stop using On Error Resume Next and On Error Goto

have a nice day
« Last Edit: April 18, 2012, 07:46:04 AM by whoknows »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: AutoCAD.NET | Handling *Exceptions
« Reply #26 on: April 18, 2012, 10:00:18 AM »
Hi,

Maybe you can handle Lisp specific exceptions with some classes :

Code - C#: [Select]
  1.     public class LispException : System.Exception
  2.     {
  3.         public LispException(string msg) : base(msg) { }
  4.     }
  5.  
  6.     public class TooFewArgsException : LispException
  7.     {
  8.         public TooFewArgsException() : base("Too few arguments") { }
  9.     }
  10.  
  11.     public class TooManyArgsException : LispException
  12.     {
  13.         public TooManyArgsException() : base("Too many arguments") { }
  14.     }
  15.  
  16.     public class ArgumentTypeException : LispException
  17.     {
  18.         public ArgumentTypeException(string s, TypedValue tv)
  19.             : base(string.Format(
  20.             "Bad argument type: {0} {1}",
  21.             s, tv.TypeCode == (int)LispDataType.Nil ? "nil" : tv.Value))
  22.         { }
  23.     }

The pseudo code in the first post may be this:

Code - C#: [Select]
  1.         [LispFunction("foo")]
  2.         public string Foo(ResultBuffer resbuf)
  3.         {
  4.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  5.             try
  6.             {
  7.                 if (resbuf == null)
  8.                 {
  9.                     throw new TooFewArgsException();
  10.                 }
  11.  
  12.                 TypedValue[] args = resbuf.AsArray();
  13.                 int i = args.Length;
  14.  
  15.                 if (i > 1)
  16.                 {
  17.                     throw new TooManyArgsException();
  18.                 }
  19.  
  20.                 if (args[0].TypeCode != (short)LispDataType.Text)
  21.                 {
  22.                     throw new ArgumentTypeException("stringp", args[0]);
  23.                 }
  24.  
  25.                 string filePath = (string)args[0].Value;
  26.                 DirectoryInfo pathInfo = Directory.GetParent(filePath);
  27.  
  28.                 if (pathInfo.Exists && Directory.Exists(filePath))
  29.                 {
  30.                     return pathInfo.FullName;
  31.                 }
  32.                 else
  33.                 {
  34.                     return null;
  35.                 }
  36.             }
  37.             catch (LispException ex)
  38.             {
  39.                 ed.WriteMessage("\nLISP error: {0}\n", ex.Message);
  40.                 return null;
  41.             }
  42.             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  43.             {
  44.                 ed.WriteMessage("\nAutoCAD error: {0}\n", ex.Message);
  45.                 return null;
  46.             }
  47.             catch (System.Exception ex)
  48.             {
  49.                 ed.WriteMessage("\nSystem error: {0}\n", ex.Message);
  50.                 return null;
  51.             }
  52.         }
  53.     }
Speaking English as a French Frog

BlackBox

  • King Gator
  • Posts: 3770
Re: AutoCAD.NET | Handling *Exceptions
« Reply #27 on: April 18, 2012, 10:03:01 AM »
Most excellent... Thank you for the example code, Gile.
"How we think determines what we do, and what we do determines what we get."

TheMaster

  • Guest
Re: AutoCAD.NET | Handling *Exceptions
« Reply #28 on: April 19, 2012, 05:31:23 PM »
Of course, you can do whatever you think is correct, but if an error happens
for some reason you didn't expect, then you will never know, and the user
will have no way to tell you what's gone wrong.
Is intentional. It is a library that provides functions to AutoLisp

I'm not sure what the calling language has to do with it. 
If the programmer is doing something wrong (e.g., has a
bug in their code), exceptions are how they find out about
them, verses their code running without error, and possibly
corrupting data.

Quote
Your ideas seem to be predicated on a presumption that your code could
never fail for reasons you didn't expect.
No. It is just the opposite I really think that my code might fail at anything. THIS IS TRUE.It seems that I'm a bit pessimistic

try{} catch {} is like "On Error Resume Next" in legacy VB/VBA, and you
can find plenty of discussion about what's wrong with the latter if you
do the research.
I think I understand how to use try/catch, but today I discovered that is not the same use an empty catch block that a system.exception.
One year ago I had a problem with SEHException (I could not fix) and today I have just discovered that can be  handled with an empty block!!!!! :ugly:

It is true that I come from the VB world and i had many prroblemas to stop using On Error Resume Next and On Error Goto

have a nice day

It's true that non-mapped exceptions can't be caught with catch( Exception ex ),
and you have to use catch {}, but catching exceptions isn't the issue, it is not
doing anything when they are caught that is the issue.
« Last Edit: April 19, 2012, 06:12:56 PM by TheMaster »

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: AutoCAD.NET | Handling *Exceptions
« Reply #29 on: May 01, 2012, 09:10:12 AM »
Now here's a nettle for you. Even if I have a throw statement somewhere to return an error to lisp, the wrong error text gets sent to lisp along with an entire error stack trace. E.g.
Code - C#: [Select]
  1.     [LispFunction("SomeLispFunc")]
  2.     public ResultBuffer SomeLispFunc(ResultBuffer args) {
  3.       if (args != null) throw new ArgumentException("Too many arguments");
  4.       // Some more code
  5.     }
Now running that in ACAD:
Code - Auto/Visual Lisp: [Select]
  1. Command: (setq return (vl-catch-all-apply 'SomeLispFunc (list "Test")))
  2. System.ArgumentException: Too many arguments
  3.    at MyLisp.MyLisp.SomeLispFunc(ResultBuffer args)
  4.    at AcMgCommandClass.InvokeWorker(AcMgCommandClass* , MethodInfo mi, Object
  5. commandObject, Boolean bLispFunction)
  6.    at AcMgCommandClass.InvokeWorkerWithExceptionFilter(AcMgCommandClass* ,
  7. MethodInfo mi, Object commandObject, Boolean bLispFunction)
  8.    at AcMgPerDocumentCommandClass.Invoke(AcMgPerDocumentCommandClass* ,
  9. gcroot<System::Reflection::MethodInfo ^>* mi, Boolean bLispFunction)
  10.    at AcMgCommandClass.CommandThunk.InvokeLisp(CommandThunk*
  11. )#<%catch-all-apply-error%>
  12.  
  13. "ADS request error"
And this was tested using both a debug and release build. Doesn't matter if VS started acad, or even if it's running.

So the problem is twofold:
  • I don't want the entire stack trace on the user's command-line, I just want to show him an error message using princ / alert (at worst, probably run some other lisp in case of some type of error). This stack is just clutter to a normal user.
  • The returned message is simply always a "ADS request error" ... so without the stack trace you have no way of passing a custom error back to lisp. And thus you can't distinguish something like a out of bounds exception from a argument exception, making such throws an all or nothing scenario.
At least that's from my understanding & testing. I hope I'm just missing something here, perhaps just a compiler setting or so. Anyone have an idea how to do this?
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.