Please throw errors instead of failing silently


Userlevel 2

It is a good practice to fail extremely loudly - if there is some issue, don't leave it up to the caller to detect the problem. Halt execution, and please throw an error.



We've been using CAD files, and the server we have been using the ZOS API didn't have Solidworks installed. Because of that, the ZOS API just silently ignores those CAD files - no logging, nothing. As a result, we have months of simulations that have produced bad results.



The answer I've gotten before is 'We rely on the user to handle errors'. This is terrible UX. How am I supposed to find problems? I make an exhaustive checklist that is 300 items long that validates each ZAR file the API ingests? How do I make that checklist in the first place? I don't see how I could have noticed this CAD issue.



At the very least, please print out potential issues to the console. The best option for UX would be to throw errors.


15 replies

Userlevel 2

If 'Sorry, you have to detect the errors' is the final answer, I can't have confidence in my simulations. I just don't have the ability to learn OS inside and out to predict all of the potential issues.



I couldn't imagine a Zemax engineer sitting over a customer's shoulder, noticing problems with their simulation, and not telling them. That's what the API is doing - unless for whatever reason it can't detect errors itself. If that's the case, I guess some big architectural overhaul is in order.

Userlevel 7
Badge +2

Hi Chris,


It seems like an odd behaviour. Can you share some example code, which demonstrates the issue? It might be helpful to other users.


Take care,


David

Userlevel 2

This is more of a general problem and design of the entire API. Here are some examples:



  • other_row.CoatScatterData.GetFaceData(2**31 - 1)

    • Should throw an error because that face doesn't exist. Instead, it returns a face data object.



  • non_sequential_component_editor.GetObjectAt(1200210)

    • Returns None instead of throwing an error. This is better than complete silence though.

    • Other functions return False or -1 or 1 (like non_sequential_ray_trace_tool.ClearDetectors(1328913298)), or like GetFaceData it could return an object. All these types of values somehow indicate something went wrong.



  • ZAR loading ignores errors loading Solidworks files, doesn't print anything/log anything

  • Opening multiple zos_system.Tools at once fails silently, no warnings

  • non_sequential_ray_trace_tool.set_SplitNSCRays('adsfads')

    • No error despite a bad input, return value is the same as setting it to a valid input




Another response could be, 'Don't make mistakes and give things bad arguments' - this is like selling cars without seatbelts and airbags. Roads without guardrails, etc. It's especially important for newbies (me) and people on a team of 1 without experienced reviewers (also me).

Userlevel 7
Badge +2

Hi Chris,


Thanks for sharing those example. Its good to keep them in mind.


I'll play around those issues when I have some spare time.


Regarding a 'None', '-1', or 'False' return value. This is the behaviour I would expect. I don't want to have to deal with automatic error handling, or error dialog boxes as this would disrupt the flow of my user interfaces.


Also, I need to double check, but from what I remember, having multiple tools open at the same time shouldn't be possible, and there should be an error thrown.


While I agree with your points, I also think one should consider the development resources at Zemax as well. They've done quite a good job at coming up with the ZOS-API, and I have yet to see something equivalent from their competitors. Also, I appreciate the fact that they delegated the error handling to us, the users, such that they can focus on implementing missing features.


Looking forward to seeing the ZOS-API becoming better, and better :)


David

Userlevel 2

Those examples are just a very few - I anticipate it being ubiquitous since I'd guess the Python API was automatically generated, not hand-written.



Fair on the return values - I'd hope for at least consistency so I could check for the same thing every time. I don't have a UI - I just have a server people submit ZAR files to and it runs simulations, so I need it to crash and burn rather than plug along. I'd rather have a disrupted flow than inaccurate results.



'one should consider the development resources at Zemax as well' agreed, and they can prioritize this however they want. I just disagree with  'it's the user's burden' as an API philosophy.

Userlevel 7
Badge +2

That makes sense. Perhaps what we can do is report those issues (in this same thread?). Once we get a collection of them, maybe we can ask the people at Zemax if they can be considered for implementation.


One thing to add in this regard, they'll probably ask for an example of those issues. It would be good if we have for each 'odd' return value, or missed error, an example code, to compare its faulty output with what it should output.

Userlevel 7
Badge +3

This sounds odd to me. First of all, SolidWorks only needs to be installed if you are loading SolidWorks files, not general CAD formats like STEP etc. Chris, can you clarify what type of CAD files you are using? If they are STEP etc files there should ne bo issue.


One thing to try is to load the ZAR archive by hand via the UI and see what errors you get. Any error generated in the UI should have an equivalent via ZOS-API. It would be a bug if no equivalent error message was returned.


That said, error handling is one of the things you do need to handle if writing at the ZOS-API level and even in ZPL. If you try to do something that cannot be done from the UI, like running multiple tools at once, I think it may be very difficult for the Zemax coders to trap those things without making the coded run slower for all users. So there is a balance of effort between the API programmer and the Zemax programmer. I'd start with whatever error messages you get from the UI: these should be replicated in ZOS-API.

Userlevel 4
Badge

There have been some changes in the way missing STEP files are reported in recent Optics Studio UI (so could also be in ZOS-API). You used to have a useful message, telling you which STEP file was missing. Now all you have in that your layouts (among other windows) will have a cryptic error message (e.g. 'Error 72: Unknown Error*). To find which STEP file is missing, you have to find the latest .log file in 'Objects\CAD Files' folder and it would have a text like 'Translation Result : File Not Found'.


 

Userlevel 2

We were using 'CAD Part: SolidWorks®'.



'error handling is one of the things you do need to handle if writing at the ZOS-API level and even in ZPL'. If you try to do something that cannot be done from the UI, like running multiple tools at once, '




This is my point - it shouldn't fall on the shoulders of API users to check for all possible errors. For a decent UX, the API should provide guardrails that say 'Oh! Looks like you don't have Solidworks installed. Please install before running a ray trace with these objects.' Instead, it says 'No Solidworks? That's okay, they probably weren't important anyway. Simulate away!' Please don't focus on just this issue though, it's a problem throughout the API - see the examples I posted above.




'I think it may be very difficult for the Zemax coders to trap those things without making the coded run slower for all users.'




It's good to consider performance, but the code certainly won't run noticeably slower for any of the use cases I mentioned. Unless something is very wrong that I don't know about.




'start with whatever error messages you get from the UI'




The API should be independent from the UI, but alright. The UI tells me I need Solidworks installed to view the files, and converts all the rows in the NCE to null objects. In the API, it converts them to null objects, but doesn't log any warnings or throw any errors. Fortunately, I can check for null objects and stop the simulation myself as a band-aid fix. Before now, though, all we knew was that something was weird about our simulations - numbers didn't match up like we expected. That leaves the entire space of all called functions, all model setup, everything to search to find the issue. Instead of the API pointing out exactly what is wrong.



I've attached the contrived ZAR we made for debugging.

Userlevel 6
Badge +2

Hi all,


Thanks for the great discussion here! I wanted to pop in and let you all know that updating error handling in the API is definitely something the developers are considering; however, it is not as high priority as completing the API roll-out. This is of course in addition to other development tasks. That isn't to say we don't already have some methods for checking for errors. I have compiled a list from previous cases. These are various methods for either ensuring the file loaded properly or for making sure there are no major system errors. 


1. The most straightforward: query some information about surface 1 in the LDE or object 1 in the NSCE. Usually checking Radius or Thickness will work. That will let you know if the file loaded properly.


2. Call TheSystem.GetCurrentStatus() immediately before and after each change to the system that could potentially cause an error in the system and therefore prevent the system from updating correctly.


3. Use the message logging functions from within the TheApplication Interface:


 



 


These properties basically toggle whether or not transient error messages are stored in a collection for retrieval.


4. If a property or public member function is of the type IMessage then an error will be returned if the function fails to run. One example is the MakeDoublePass tool in the ILensDataEditor Interface. This tool is an IMessage type:


 



 


When an LDE-based tool (like Make Double Pass) runs successfully, it will return null. When it is not able to run, it will return an IMessage interface. This interface contains two items:



  1. ErrorCode (an enumerated list of potential problems)

  2. Text (a string output of the encountered error message)


To make sure your tool has run, you can use the following line:


val = TheLDE.RunTool_MakeDoublePass(4);


Adding a variable val as a placeholder will allow you to build an IF statement which checks to see if val is empty or not. If the tool fails to run, you can access the errors with the following:


error = char(val.ErrorCode);


message = char(val.Text);


 


Chris - I haven't tested these in your ZAR file yet, but I think 2 or 3 might be useful to you. Let me know if not!


Best,


Allie

Userlevel 2

Perfect, thank you for your response (and calmness despite my lack of calmness 🙂). Checking the status didn't help with the Solidworks problem, but logging will help. I see the messages I need there.



In the short term, I'd recommend turning on message logging by default. That could prevent a lot of headaches while you're working on other features, and it's a quick fix. As soon as someone creates an application object, call BeginMessageLogging(), format the output somehow, and print it to the console.



Better to have too many log messages than not enough.

Userlevel 3
Badge +4

I’m checking out this thread and I’m not sure if anything has changed from the original post.

To summarize:

How many places do I check to see if there’s a problem with the model?

Case in point.  I am using the Lens Catalog and inserting a lens.  I want to see if I can buy a lens to get a solution rather than designing a custom element.  I need to do a lot of checking with these catalog lenses:

  • Do I need to add a glass?  (these are not added automatically)
  • Can I add the right catalog to make the model of the catalog lens work?
  • Does it transmit light at the desired wavelength?

I’m not sure how many places I need to check.  Perhaps just:

TheApplication.PrimarySystem.GetCurrentStatus()

Once I investigate this, the documentation says:

ZOS-API help

So, what do I do?  Check for null or length or ??
 

 

So… get the response, convert to a char and check for length?

Userlevel 3

Jumping in here to say that I agree with Chris, Ray, and Brian.  The API documentation is lacking, and error checking isn’t very good and can cause big problems that are frustrating and time consuming to figure out.  Given the price increases over the past few years, the burden on the user is much too high, 

Userlevel 3

2. Call TheSystem.GetCurrentStatus() immediately before and after each change to the system that could potentially cause an error in the system and therefore prevent the system from updating correctly.

Hi All,

We also have had our issues with the API failing silently, also for trivial things like trying to open a file which doesn’t exist. Within ZOSPy we aim to implement some of the more basic checks (for example checking if the file exists), but I agree that this is something OpticStudio should give back as that is the routine which tries to open the file. 

However the “solution” Allie proposes, might also be useful. @chaasjes shall we explore if this might be easy to implement in ZOSPy 

Userlevel 3
Badge +4

My recent experience with this issue was inserting a lens from the Lens Catalog.  Before that moment, I’d never used the API in a manner that forced me to check GetCurrentStatus().

The challenge I faced was:

When inserting a lens from the lens catalog, there is no way to know if the material catalogs being used in the model are consistent with the lens in the catalog.  One needs to

  1. Trap the message from GetCurrrentStatus
  2. Search through all material catalogs to find the catalog that has the glass that is required
  3. Add that material

I have only encountered one message with: GetCurrentStatus, that of an undefined glass.  It is revealed as a message in text.  I have no idea what other messages may exists and how to parse them.

What other messages have other people encountered?

Reply