return error with generics - An object of type convertible to 'foo' is required

Having a problem specifying the proper return value in a Try Catch block. What specifically do I need to return at the end of my Try Catch. I’m intermediate level scripter but have never used generics before.
Any feedback appreciated.

private static T LoadData<T>(string filePath)
    {
              try{
        return JsonUtility.FromJson<T>(File.ReadAllText(filePath));
            }
        catch(Exception e)
        {
            // Something went wrong, so lets get information about it.
            Debug.Log(e.ToString());
            return ?????;
        }
    }

This has nothing to do with the try/catch per se. The same thing would happen with an if/else. You need to return something of type T.

default(T) will probably compile, but for value types it might be hard to detect the error from the caller.

As mentioned, you can get away with returning the type’s default, which the compiler knows. It’s null for reference types and nullables, and a default-constructed value for value types (e.g. fields have their default value).

It’s clearly possible to implement it like that. However, you’ll make things harder for the caller if your method swallows all the information, and the caller needs to make assumptions “default” means the operation has failed.
As @PraetorBlue has already pointed out, the default of value types could as well be the actual value - there’s no way to determine whether success or failure was the result of the operation.

That’s why you should change the way you handle the different outcomes.
There are multiple ways:

  1. just let it throw the exception so that the caller can actually handle it

  2. catch it, do something (logging for example), and re-throw (but only via “throw”, not via “throw e”).

  3. catch it, wrap it into your own exception type if you want to generalize these types of problems for various underlying utlities etc
    For example, imagine you have a JSON and an XML serializer. Both are likely going to throw common IO exception, but their parsing exceptions may differ. You could catch parsing exceptions, and throw your own in order to map a category of errors to a specific exception type.

Whenever exceptions are not desired:

  1. use the Try-pattern: have a boolean as return value and an out parameter for the actual result (e.g. data that was read)
    The caller doesn’t need to make assumptions, as “true” means the operation succeeded (and the actual data is available in the variable passed as the out-argument), whereas “false” means something went wrong and there’s likely nothing you can use in the variable you passed as “out”.

  2. A variation of #4, except that you supply additional information about the outcome by turning the exception into an object/value. That information can either be returned, or be an additional out-param when you want to keep the boolean as return-value as an indication for quick success/failure indicator.

1 Like