Real-Serious-Games / C-Sharp-Promise

Promises library for C# for management of asynchronous operations.
MIT License
1.19k stars 149 forks source link

Rejecting a promise that is not of type System.Exception #82

Closed mattbadley closed 6 years ago

mattbadley commented 6 years ago

I'm trying to integrate this library with PlayFab (a cloud based games backend). I have it working except for the error side of things.

Here's some code:

public IPromise<LoginResult> Login()
{
    var promise = new Promise<LoginResult>();

    var request = new LoginWithIOSDeviceIDRequest();

    PlayFabClientAPI.LoginWithIOSDeviceID(request, (LoginResult result) => promise.Resolve(result) , (PlayFabError error) => promise.Reject(new System.Exception()));

    return promise;
}

I then setup the promise chain in the following way -

Login()
    .Then(result => {
        PlayFabId = result.PlayFabId;
    })
    .Catch(error =>
        Debug.Log("An exception occured while loging in! " + error)
    );

The problem is with promise.Reject. I can only pass in an object which is of type System.Exception... but Playfab returns errors of type PlayFabError.

How can I set this up to use PlayFabError objects?

Also I've put the lambda functions inline (the success and fail callbacks), but this doesn't feel right. Is there a better way to format this?

Any help would be appreciated!

nah0y commented 6 years ago

Hello,

Does PlayFabError extends System.Exception? If yes, then I think you should be able to use it. If not, maybe you need to create your own class that extends System.Exception and contains a PlayFabError variable?

RoryDungan commented 6 years ago

In theory we could support rejecting promises with objects other than exceptions but it was originally designed like that because .Then( ... ).Catch(ex => ... ) is meant to roughly model a regular try { ... } catch (Exception ex) { ... } block.

In Javascript promises you can reject a promise with any object, which makes sense because you can also throw any object. In C# however, you can only use the throw keyword with an exception. For now I'd recommend making your own custom exception type that extends System.Exception and can wrap up a PlayFabError.

In response to your formatting question, it's really up to you what style you think looks best. I usually split function arguments onto separate lines if the line is more than around 80-90 characters. You probably also can leave out the type declaration for the lambda function:

PlayFabClientAPI.LoginWithIOSDeviceID(
    request, 
    result => promise.Resolve(result), 
    error => promise.Reject(new System.Exception())
);
mattbadley commented 6 years ago

Thanks for the comments - wrapping the PlayFabError in my own custom class was a good solution and works well!