Search Unity

Try/Catch not working right? Or I'm not...

Discussion in 'Scripting' started by victus_maestro, Apr 4, 2021.

  1. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    Evening all! I've found questions here along these lines, but this seems to be a fairly unique issue I've found.

    I'm trying to toggle opening a serial port to connect an Arduino to my Unity project, and that's all working fine. The only issue I have is related to the command to open the port being executed without a serial connection being plugged in...it throws an IOException that the port doesn't exist. Perfectly understandable.

    To handle this, I added a try (which opens the connection) and catch (System.IO.IOException) but it doesn't reflect this at all, just throws the same exception. I even tried just with catch(System.Exception) and it still threw the same exception in the console.

    I often see (System.Exception e) being used in the C# documentation, but that simply tells me that "e is defined but never used" and doesn't change the behavior of the catch at all.

    What am I doing wrong? Really, I just need to handle the exception so that it doesn't cause trouble in the build, and it's for a behind the scenes feature that's really not mission-critical. I just have an issue with exceptions not being handled before I build.
     
  2. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    691
    When you say "e is defined but never used", that's what Unity is warning you about, correct? In that block, you can print out e's value, that should at least eliminate the warning.

    I'm not sure how all this relates to builds, I would guess it's probably not relevant as there's no console equivalent. This is assuming that when you try to open the port and it's not connected, it's just an error and not a freeze/crash. If it just gives the error and everything continues to run, I imagine the build will be fine.
     
  3. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    Ah, makes sense. If it's not going to freeze the game, then it's really not too big a deal. I just wasn't sure as some exceptions will halt everything but this is a fairly minor thing that only happens under very specific and known conditions.

    Thanks for the insight, I'll play around with it some more and see what I can find, but I'm not excessively worried.
     
  4. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    691
    Note that these are my (only somewhat) educated guesses...but yeah, testing whether the exceptions actually cause freezes or crashes would be the key factor.
    Microcontroller stuff is fun, I need to get back into it. Haven't tied them into Unity yet, used Max/MSP for them in the past, but would be cool to connect them to a game or simulation. The hardware is so cheap, you can build just about anything affordably.
     
  5. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    Yeah, the fact that the play mode doesn't immediately hang when the error comes up is a good sign, though I could do a build while I'm still in a minimal state to test the functionality. It's not for a public release feature (so far as I've planned), so someone using it should know to have the Arduino plugged in and the correct port set before running it.

    This particular use case is to run a mechanized physical camera rig that is synced to a virtual camera for mixed reality. The camera element should arrive next week, then we'll see if I'm just crazy. But it is a lot of fun!
     
    seejayjames likes this.
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,004
    First of all when you have issues with some of your code, include the relevant parts of your code. While your description of your setup is quite detailed. There could be countless of tiny mistakes we simply do not see.

    Generally a catch clause can come in two versions. You can either just specify the exception type you want to catch, or you can additionally declare a local variable that will hold the exception instance. This is the "e" you talked about. You only want to declare a variable in case you want to access any additional information of the IOException instance. If you don't, just don't declare a variable.

    An exception in general is, as the name suggests, an exceptional state of your program that makes it impossible to continue executing. Native exceptions are even a feature of the protected mode of your CPU. There's always an active exception handler that will be executed whenever an exception is raised. Most operating systems will simply kill applications that do not handle exceptions themselfs. An exception in the system core / kernel will result in a classic crash / kernel panic and will halt / reset the whole computer. On modern systems there are usually many levels of exception handlers.

    Unity for example will automatically catch exceptions that are raised in most engine callbacks. So no matter what you do inside Update or Start, Unity will catch any exceptions, logs them to the console and continue with the next frame.

    Note that in C# (and most other languages that has a try-catch block) you can have multiple catch clauses to handle different exceptions. It is possible to simply use a catch-em-all clause, but it's generally recommended to be as specific as possible. Simply catching and swallowing any exception may hide other issues your code may have and you will never notice. Exceptions are a great debugging tool.

    Note that certain classes may produce errors / generate warnings or error logs without actually throwing an exception. In general it's always better to use defensive programming. Exceptions should not be used as control flow (through they often are). Checking the state before you do something that goes wrong because of an invalid state is always the better solution. Excpetions should always be that, exceptions.

    Finally note that exceptions do not cause hangs or freezes. Most SerialPort methods are blocking calls which block execution until they are completed. That's why you should almost always use things like the SerialPort class on a seperate thread. As I said, without seeing the code it's hard to tell what's your actual issue(s).
     
    victus_maestro and seejayjames like this.
  7. victus_maestro

    victus_maestro

    Joined:
    Apr 21, 2019
    Posts:
    21
    Thanks for the long and insightful reply, Bunny83. Usually I'm not as prone to lazy coding, but late nights and lack of sleep with a 5-month old left me chasing the symptom, not the root cause.

    Following your recommendation regarding an ounce of prevention and such, I gutted that whole part of my code and came at it blind as from the perspective of the program itself, not working from the assurance that the COM port would be inevitably unchanging. As such, when you trigger the method, it now polls all available serial ports and automatically opens an available one at the correct designation.

    It is now working great, and accurately telling me if I can or cannot create communications at the current time... no more exceptions! Thanks again!

    If seeing the functional code would be beneficial, I can add it here in the replies.