fix(ios): validate signingUrl and emit the documented error codes - #7
Merged
Conversation
DSMEnvelopesManager.presentCaptiveSigning validates nothing and presents unconditionally, so a blank or non-https URL rendered an empty signing controller whose completion never fired, leaving the JS promise unsettled. CaptiveSigningUrlRecord defaults signingUrl to "", so an omitted field reached the SDK without a malformed URL being involved at all. The guard sits after the isInitialized check and before the stateQueue.sync that claims pendingCompletion, so a rejected URL never occupies the slot and a later valid call is not refused as "already in progress". Same exception type and message as the Android guard, so both platforms reject identically. Closes #5
Expo derives a code from the exception class name when none is set, so NotInitializedException reached JS as ERR_NOT_INITIALIZED rather than the not_initialized the error table has always listed. The Android module got explicit codes in the previous change, which left the two platforms disagreeing on every code. All five exceptions now set their code. Both failure branches in the module hard-coded "signing_failed", which flattened presentation_failed and hid which stage failed. They now forward the failure's own code. promise.reject(error) is not the alternative here: it wraps anything that is not an Exception, so a raw SDK NSError would surface as ERR_UNEXPECTED.
Add presentation_failed to the error table and state that both platforms emit the codes verbatim, since matching on the ERR_-prefixed variants was the only thing that worked on iOS before this release.
Keeps local coding-agent state out of the repo and the npm tarball.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the iOS module up to the contract the README has always described and the Android module now honours. Both changes are breaking, so they belong in 2.0.0 or they wait for 3.0.0.
Closes #5.
Validate
signingUrl(#5)DSMEnvelopesManager.presentCaptiveSigning(withPresenting:signingUrl:...)validates nothing and presents unconditionally. A blank or non-httpsURL rendered an empty signing controller whose completion never fired, so the JS promise never settled.CaptiveSigningUrlRecorddefaultssigningUrlto"", which means an omitted field reached the SDK without a malformed URL being involved at all.The guard sits after the
isInitializedcheck and before thestateQueue.syncthat assignspendingCompletion, so a rejected URL never claims the slot and a later valid call is not refused as "already in progress". Same exception type and message string as the Android guard, so the two platforms reject identically.Emit the documented error codes
Expo derives a code from the exception class name when none is set, so
NotInitializedExceptionreached JS asERR_NOT_INITIALIZEDrather than thenot_initializedthe error table has listed since 1.0.0. Android got explicit codes in the previous release, which left the platforms disagreeing on every single code. All five exceptions now set theirs.Separately, both
.failurebranches inDocuSignModule.swifthard-coded"signing_failed", which flattenedpresentation_failedand hid which stage had failed. They now forward the failure's own code.promise.reject(error)is not the alternative: it wraps anything that is not anException, so a raw SDKNSErrorwould surface asERR_UNEXPECTED.Migration
ERR_NOT_INITIALIZEDnot_initializedERR_NOT_LOGGED_INnot_logged_inERR_LOGIN_FAILEDlogin_failedERR_SIGNING_FAILEDsigning_failedERR_PRESENTATION_FAILED(never reached, flattened to signing_failed)presentation_failedRejection messages on the failure path are now the underlying error text on its own, where they previously carried a
DocuSign signing failed:prefix.Verification
swiftc -parseclean on all three Swift files.npm run build,npm run lintand 18/18 Jest tests pass.Worth stating plainly: CI compiles no Swift and runs no iOS tests, so nothing in this repo can catch a type error in these files. The native changes are verified by parsing and by reading against the Android implementation they mirror. A device run against a real envelope before tagging 2.0.0 would be the honest bar.
Not included
The
.failuredouble-emit that Android had does not exist here. The manager's SDK-error path callsresolvePending(.success(outcome))withstatus: "error", so the module's failure branch never runs for signing errors. Different from Android, internally consistent, left alone.