Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Kotlin code to improve error handling #317

Merged
merged 50 commits into from
Dec 7, 2023

Conversation

krocard
Copy link
Contributor

@krocard krocard commented Nov 10, 2023

Problem (PRN-74 PRN-92)

The codebase had many issues:

  • invalid null parameters were ignored instead of reporting an error
  • invalid state (module not loaded) were ignored instead of reporting an error
  • many functions were taking unnecessary null parameters, returning null unnecessarily
  • errors were not reported
  • some promise were not resolve (deadlock if awaited)
  • exception do not reject promisses

Changes

Simplify the code and improve error visibility by:

  • Errors are bubbled up to the caller with @ReactNative's promise.reject instead of ignoring them or logging them.
  • Refactor json serialization to use null operator ?. rather than operating on null values.
  • Make toJson extension function to easily chain ?. operations
  • Make Json.toXXX extension function to easily chain ?. operations
  • Add XXXModule variant that throws an exception if the module are not loaded, which should never happen
  • Wrap all @ReactNative methods in a catch to report any exception instead of crashing the app
  • Introduce a base Bitmovin module for helper functions
  • Wrap promise in a strongly typed interface
  • All @ReactCommand promisses are guarantied to be resolved or rejected
  • Exception in the PlayerViewManager are logged instead of crashing the app

📚 Other PRs for this issue

Checklist

  • 🗒 CHANGELOG entry if applicable

Refactor json serialization to use null operators rather than
operating on null values.

No behaviour is changed.

PRN-74
@krocard krocard self-assigned this Nov 10, 2023
@krocard krocard marked this pull request as ready for review November 13, 2023 09:00
@krocard krocard requested review from matamegger, zigavehovec and strangesource and removed request for strangesource November 13, 2023 09:01
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure Hide whitespace is ticked to review this file.

/**
* Converts an arbitrary `json` to `PlayerConfig`.
* @param json JS object representing the `PlayerConfig`.
* @return The generated `PlayerConfig` if successful, `null` otherwise.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @param and @return documentation was only describing the type and name of the parameter, which is against our style guide. They have thus been removed.

Copy link
Contributor

@matamegger matamegger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice improvements!

I think we need some more work on the uiManager/Promise thing, but even that is already a good starting point!

Copy link
Contributor

@matamegger matamegger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat that you found a solution for the Promises. This makes future review and coding a lot easier 👍

As discussed, there are still some errors, but apparently the fault is on the Arguments.fromList.
Also, I am not sure if the nullability is right on all the promises. I think we have to align with the type that is defined in the TS API.

@@ -49,7 +50,7 @@ export function PlayerView({
fullscreenHandler,
customMessageHandler,
isFullscreenRequested = false,
scalingMode,
scalingMode = ScalingMode.Fit,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alternative is to default in the Kotlin code on null.
Chose to default in the TS code aligned with isFullscreenRequest.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this could change the behaviour a bit, E.g. on iOS we don't call anything on the playerView if nothing is set:

switch scalingMode {
case "Zoom":
    playerView.scalingMode = .zoom
case "Stretch":
    playerView.scalingMode = .stretch
case "Fit":
    playerView.scalingMode = .fit
default:
    break
}

I think I would prefer not to change this, at last within this PR.

Copy link
Contributor Author

@krocard krocard Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think ignoring the command on the native side if it's invalid is the right approach (and it goes against the PR goal of reporting invalid states).
The alternative is to avoid sending the command if no scaling mode is requested: d77c955

Copy link
Contributor

@zigavehovec zigavehovec Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed - since using a default value makes a call on playerView that didn't happen before, emitting an additional event (ScalingModeChangedEvent (_DefaultScalingModeService.swift:38)) let's use the alternative approach 🙂

We can improve on this in a follow up PR.

Copy link
Contributor

@zigavehovec zigavehovec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome improvements 💪
I noticed some things that I think we should address, but looking very good already!

@@ -49,7 +50,7 @@ export function PlayerView({
fullscreenHandler,
customMessageHandler,
isFullscreenRequested = false,
scalingMode,
scalingMode = ScalingMode.Fit,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this could change the behaviour a bit, E.g. on iOS we don't call anything on the playerView if nothing is set:

switch scalingMode {
case "Zoom":
    playerView.scalingMode = .zoom
case "Stretch":
    playerView.scalingMode = .stretch
case "Fit":
    playerView.scalingMode = .fit
default:
    break
}

I think I would prefer not to change this, at last within this PR.

Copy link
Contributor

@matamegger matamegger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing to add to @zigavehovec s comments.
After those topics are resolved this is fine to be merged.

Copy link
Contributor

@zigavehovec zigavehovec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Let's get this merged 💪

@krocard krocard merged commit fef1113 into development Dec 7, 2023
9 checks passed
@krocard krocard deleted the PRN-74/refactor--improve-null-safety branch December 7, 2023 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants