Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Best Practices for Reporting Errors to Users?

    Cinema 4D SDK
    python
    3
    4
    762
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • dskeithbuckD
      dskeithbuck
      last edited by dskeithbuck

      Hi,

      I've been seeing a lot more usage of code like raise ValueError("Invalid path selected") in the Python examples. As I understand it, these errors tend to get surfaced in the Console - which is useful to developers, but less useful to Users.

      Here's a simple script that asks a user to select an image in a folder containing multiple images.

      import c4d
      
      def get_images_path():
          image_path = c4d.storage.LoadDialog(
              type=c4d.FILESELECTTYPE_IMAGES,
              title="Select an image in the folder you want to bulk rename",
              flags=c4d.FILESELECT_LOAD
          )
          
          if not image_path:
              raise ValueError("Valid image path not selected.")
          
          return image_path
      
      def main():
          images_path = get_images_path()
          
          c4d.gui.MessageDialog(images_path)
      
      if __name__=='__main__':
          main()
      

      How should I gracefuly accept a user hitting "Cancel"? How should I provide the user with a helpful error if they've selected the wrong filetype (let's for example pretend I'm looking for .png files rather than misc image formats)?

      Should we use popup messages? Status bar updates? Console prints?

      Do I need to do something like:

      try:
          images_path = get_images_path()
      except ValueError as error:
          c4d.gui.MessageDialog(error)
      

      ...every time I call any method that might throw an error? Or is there a way to auto-promote exceptions/errors as alert dialogs/status updates?
      Thanks,

      Donovan

      1 Reply Last reply Reply Quote 0
      • S
        s_bach
        last edited by

        Hello,

        there is no "official" way of handling or reporting errors in Python scripts. You can do whatever fits your needs or the needs of your user best. Why do you think the console is not useful to users?

        The only thing to consider are general best practices regarding software design. E.g. to only show a (modal) dialog when you know that a user is interacting with the software, not in some sub-function.

        Another philosophical discussion is, what actually is an error? An error should be returned by a function that failed; but what does that mean? What should happen if an error is detected? (Here is some video about this topic I just recently watched:

        )

        For argument's sake, lets say an error is when something in your code, you are 100% sure should and must work, didn't work. So your program shuts down, if such such an "error" was detected.

        In your example, LoadDialog() is a function that - in my opinion - cannot fail. Either the user selects a folder or he presses "Cancel". Both are fine results. And if the user tells you to abort, you can simply exit your program.

        Similarly, when the user selects the wrong file type, that's not a program error. Compare that with a user entering a wrong password somewhere - that is not an error, but something to expect. Providing feedback to the user and handling errors are two different things.

        def handleError(error):
            print(error)
            c4d.gui.MessageDialog(error)
        
        def getImagePathFromUserInteraction():
            res = c4d.storage.LoadDialog(
                type=c4d.FILESELECTTYPE_IMAGES,
                title="Select an image in the folder you want to bulk rename",
                flags=c4d.FILESELECT_LOAD
            )
            
            if res == None:
                return False
            
            return res
        
            
        def main():
        
            # UI interaction
            res = getImagePathFromUserInteraction()
            
            if res == False:
                # nothing to do, lets go home
                print("script aborted by user")
                return
            
            # do actual work 
        
            try:
                doSomething(res)
                doSomethingElse(res)
                
            except ValueError as error:
                handleError(error)
                return
            
            # show result in the UI
            c4d.gui.MessageDialog(res)
        

        best wishes,
        Sebastian

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 1
        • ferdinandF
          ferdinand
          last edited by ferdinand

          Hi,

          I assume you are aware of this, but exceptions and errors are a kind of 'problematic' topic for Python in general, because of the fact that it is a typeless language and the resulting constant need of input sanitisation (if you want to play things safe).

          I also think that the Google Python style guide [1] is always a good thing to follow (although someone will probably furiously point out that they do not govern the Python language). They have a paragraph on exception and error handling. One thing I could spot in your example is the verbosity problem. Do not throw exceptions or display errors like "Invalid file path selected.", use something like "Execution stopped: {} is an invalid file path.".format(some_path). Google shows that problem in their examples too.

          For your actual question: Since Cinema is thankfully rather conservative with throwing error dialogs itself, I would follow this approach and only open a dialog for things that are absolutely critical (so basically never in a plugin) and use the status bar for anything else. Cinema's status bar is somewhat inconspicuous / hard to notice, a feature to let it flash for an error would be nice.

          This ultimately ties to the topic of the difference between errors and exceptions, but since you both already covered that subject indirectly, I will leave it at that.

          Cheers
          zipit

          [1] https://github.com/google/styleguide/blob/gh-pages/pyguide.md

          MAXON SDK Specialist
          developers.maxon.net

          1 Reply Last reply Reply Quote 1
          • dskeithbuckD
            dskeithbuck
            last edited by

            @s_bach & @zipit - Thank you both for the thoughtful replies!

            I think I'll opt for the status bar for most user-facing feedback, and console logging for anything bigger. Watching the "What could possibly go wrong?" talk now.

            1 Reply Last reply Reply Quote 0
            • First post
              Last post