Author Topic: Exception OverKill??  (Read 1965 times)

0 Members and 1 Guest are viewing this topic.

Keith Brown

  • Swamp Rat
  • Posts: 601
Exception OverKill??
« on: March 17, 2014, 04:44:07 PM »
I am writing a couple functions for lisp (of which i know very little) and implimenting Giles lisp exception classes as well as a few of my own and I wonder if I am going a little overboard trying to define the exact exception that is happening.


Here is my code.


Code - Text: [Select]
  1. public class Commands
  2.     {
  3.         [LispFunction("ImportLabelCurveStyle")]
  4.         public bool ImportLabelCurveStyle(ResultBuffer resultBuffer)
  5.         {
  6.             var editor = Application.DocumentManager.MdiActiveDocument.Editor;
  7.             try
  8.             {
  9.                 TypedValue[] arguments = resultBuffer.AsArray();
  10.  
  11.  
  12.                 if (resultBuffer == null || arguments.Length < 2)
  13.                 {
  14.                     throw new TooFewArgsException();
  15.                 }
  16.  
  17.  
  18.                 if (arguments.Length > 2)
  19.                 {
  20.                     throw new TooManyArgsException();
  21.                 }
  22.  
  23.  
  24.                 if (arguments[0].TypeCode != (short) LispDataType.Text)
  25.                 {
  26.                     throw new ArgumentTypeException("Style Name", arguments[0]);
  27.                 }
  28.  
  29.  
  30.                 if (arguments[0].Value.ToString() == string.Empty)
  31.                 {
  32.                     throw new ArgumentEmptyException();
  33.                 }
  34.  
  35.  
  36.                 if (arguments[1].TypeCode != (short)LispDataType.Text)
  37.                 {
  38.                     throw new ArgumentTypeException("Style Drawing Path", arguments[1]);
  39.                 }
  40.  
  41.  
  42.                 if (arguments[1].Value.ToString() == string.Empty)
  43.                 {
  44.                     throw new ArgumentEmptyException();
  45.                 }
  46.  
  47.  
  48.                 if (!File.Exists(arguments[1].Value.ToString()))
  49.                 {
  50.                     throw new FileNotFoundException("Unable to find file", arguments[1].Value.ToString());
  51.                 }
  52.  
  53.  
  54.                 var styleName = (string) arguments[0].Value;
  55.                 var stylePath = (string) arguments[1].Value;
  56.  
  57.  
  58.                 if (LabelCurveStyleCloningHelper.ImportStyle(styleName, stylePath))
  59.                 {
  60.                     return true;
  61.                 }
  62.  
  63.  
  64.                 return false;
  65.  
  66.  
  67.             }
  68.             catch (LispException exception)
  69.             {
  70.                 editor.WriteMessage("LISP error: {0}\n", exception.Message);
  71.                 return false;
  72.             }
  73.  
  74.  
  75.             catch (Autodesk.AutoCAD.Runtime.Exception exception)
  76.             {
  77.                 editor.WriteMessage("\nAutoCAD error: {0}\n", exception.Message);
  78.                 return false;
  79.             }
  80.  
  81.  
  82.             catch (System.Exception exception)
  83.             {
  84.                 editor.WriteMessage("\nSystem error: {0}\n", exception.Message);
  85.                 return false;
  86.             }
  87.         }
  88.     }


I just wonder if I am trying to catch too many exceptions?  I wanted the description of the issue to be very clear for the LISP programmer.   And one last question.  What is the preferred return type for a lisp function?  In the above example i am returning true/false to signal successful completion but is there a better way?
Keith Brown | AutoCAD MEP Blog | RSS Feed
AutoCAD MEP 2014 / Revit MEP 2014 / EastCoast CAD/CAM addon / Visual Studio 2013

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: Exception OverKill??
« Reply #1 on: March 17, 2014, 06:52:34 PM »
Hi Keith,

First, you should check if resultBuffer is null (the LISP function was called with non arguments) before doing resultBuffer.AsArray() because if resultBuffer is null it may crash AutoCAD.

Code - C#: [Select]
  1. [...]
  2. if (resultBuffer == null )
  3. {
  4.     throw new TooFewArgsException();
  5. }
  6.  
  7. TypedValue[] arguments = resultBuffer.AsArray();
  8.  
  9. if (arguments.Length < 2)
  10. {
  11.     throw new TooFewArgsException();
  12. }
  13. [...]

To reply your question, as both Autodesk.AutoCAD.Runtime.Exception and LispException inherits from System.Exception, catching system exception will catch all.
By my side I use different catches if I want the user knows where and why was thrown the exception: LispException is due to an error in the calling LISP function (mainly arguments), AutoCAD exception is due to an exception related to the execution in autoCAD and system.Exception for all others ones.

About the return value, returning a boolean (T or nil in LISP) may be a good idea if LabelCurveStyleCloningHelper.ImportStyle() method retuns a boolean too, and may return false.

For me, the issue is the function will return nil (false) as well if LabelCurveStyleCloningHelper.ImportStyle() returns false or if an exception is thrown, and the user may not see the message (which displays in the command line but not in the Visual LISP console).
This is why, in case of an exception, I'd rather display an alert box and rethrow the exception so that the LISP execution stops, as it seems there's no way to reproduce the LISP error behavior from .NET (see here).

Code - C#: [Select]
  1. catch (LispException exception)
  2. {
  3.     Application.ShowAlertDialog(string.Format("LISP error: {0}\n", exception.Message));
  4.     throw;
  5. }
Speaking English as a French Frog

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Speaking English as a French Frog