[W-23059473] Introduce SFOAuthErrorCode enum for token endpoint error responses - #4094
Conversation
…-23059473) Replaces raw kSFOAuthErrorType* string comparisons with a typed @objc Swift enum mirroring the server-side OauthErrorCode.java wire values (~42 distinct strings). Adds errorCode property to SFSDKOAuthTokenEndpointErrorResponse, updates SFOAuthCoordinator to switch on the enum, adds client_blocked/client_blocked_retry to the NSError integer code mapping, and deprecates all kSFOAuthErrorType* constants in SFSDKOAuthConstants.h.
Clang Static Analysis Issues
Generated by 🚫 Danger |
|
||||||||||||||
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #4094 +/- ##
==========================================
- Coverage 70.79% 68.70% -2.10%
==========================================
Files 246 247 +1
Lines 21633 21687 +54
==========================================
- Hits 15316 14900 -416
- Misses 6317 6787 +470
🚀 New features to boost your workflow:
|
|
||||||||||||||
client_blocked and client_blocked_retry should be handled via the new SFOAuthErrorCode enum, not by extending the legacy NSError integer code mapping. Callers switch on response.error.errorCode, not error.code.
…useDpopNonce Names now match server-side OauthErrorCode.java (core-264 main): clientBlocked → appAttestationFailed (wire: client_blocked) clientBlockedRetry → appAttestationFailedRetry (wire: client_blocked_retry) Also add two missing distinct wire values from core-264: invalidDpopProof (invalid_dpop_proof) useDpopNonce (use_dpop_nonce)
| } else if ([type isEqualToString:@"invalid_request"]) { | ||
| code = kSFOAuthErrorInvalidRequest; | ||
| } else if ([type isEqualToString:kSFOAuthErrorTypeInactiveUser]) { | ||
| } else if ([type isEqualToString:@"inactive_user"]) { |
There was a problem hiding this comment.
I was wondering why inactive_user wasn't in the new code set but then I saw on the server side it falls under "invalid_grant". Is there a way to get the sub-category too?
There was a problem hiding this comment.
Yes — sub-categories are accessible via error_description. The server populates that field from OauthErrorCode.getDescription(), which is the human-readable description string in the server enum (e.g. "inactive user", "inactive organization", "expired access/refresh token", etc.). The SDK already parses and exposes this as tokenEndpointErrorDescription on SFSDKOAuthTokenEndpointErrorResponse, so callers can combine an errorCode == SFOAuthErrorCodeInvalidGrant check with a string comparison on errorDescription to distinguish sub-cases if needed.
| if (![json isKindOfClass:[NSDictionary class]]) { | ||
| NSString *errorDesc = [NSString stringWithFormat:@"Expected NSDictionary for JWT token response, received %@ instance.", NSStringFromClass([json class])]; | ||
| NSError *error = [SFSDKOAuth2 errorWithType:kSFOAuthErrorTypeJWTLaunchFailed | ||
| NSError *error = [SFSDKOAuth2 errorWithType:@"jwt_launch_failed" |
There was a problem hiding this comment.
This is hardcoded now because the client-side is creating the error?
There was a problem hiding this comment.
Correct — this is a client-side error, not a server wire value. The JWT response is malformed (wrong type), so the SDK generates the error locally rather than receiving it from the server. jwt_launch_failed was previously held in the kSFOAuthErrorTypeJWTLaunchFailed constant (now deprecated), but since this error string is not a server-defined wire value it isn't in SFOAuthErrorCode. The raw string is used directly here since the deprecated constant is no longer the preferred reference.
… unit 38/49) Replace brittle OAuth error string comparisons with a typed enum. NEW SFOAuthErrorCode.swift (45 server error values + .unknown, from(_:) parser, wireValue mapping, + SFOAuthErrorCodeHelper ObjC bridge) added verbatim and wired into the SDKCore target. SFSDKOAuthTokenEndpointErrorResponse (Swift twin) gains an errorCode property set via SFOAuthErrorCode.from(errorType); SFOAuthCoordinator's Lightning-URL diagnostic now branches on errorCode == .unsupportedGrantType. Legacy kSFOAuthErrorType* constants marked __deprecated_msg (retained). De-ref .m/.h ref-synced (SFSDKOAuthConstants.h verbatim; SFOAuthCoordinator.m + SFSDKOAuth2.m hunks surgical). SFSDKOAuth2.h is a migration tombstone (property lives in the Swift twin). Tests: new SFOAuthErrorCodeTests.swift (8) + SFOAuthCoordinatorLightningURLTests +4 hunk. SDKCore builds green (0 new warnings); 13 tests pass. Escalation: OAuth error-handling surface -> PR-flag. Advances upstream-sync marker ab84f31 -> 6993d6b.
Summary
SFOAuthErrorCode.swift— a typed@objcSwift enum mirroring the ~42 distinct wire values from the server-sideOauthErrorCode.java(core/identity-common-api), plus an.unknownfallbackerrorCode: NSInteger(typed asSFOAuthErrorCode) property toSFSDKOAuthTokenEndpointErrorResponse, populated at init timeSFOAuthCoordinator -handleResponse:to compareerrorCodeenum instead of string-comparing againstkSFOAuthErrorTypeUnsupportedGrantTypeclient_blockedandclient_blocked_retryto the+errorWithType:description:integer code mapping (previously fell through tokSFOAuthErrorUnknown = 666)kSFOAuthErrorType*constants inSFSDKOAuthConstants.hwith a pointer to the new enumFiles Changed
SFOAuthErrorCode.swift(new) — 42 enum cases +.unknown+wireValue+from()factory +SFOAuthErrorCodeHelperObjC bridge classSFSDKOAuth2.h—errorCodeproperty onSFSDKOAuthTokenEndpointErrorResponseSFSDKOAuth2.m— populate_errorCode; addclient_blocked/client_blocked_retryint codesSFOAuthCoordinator.m— enum comparison forisUnsupportedGrantTypeSFSDKOAuthConstants.h— deprecate 18kSFOAuthErrorType*constantsSFOAuthErrorCodeTests.swift(new) — 6 unit tests (known values, nil, empty, unknown, round-trip)SFOAuthCoordinatorLightningURLTests.swift— derive test wire values from enumwireValueSalesforceSDKCore.xcodeproj/project.pbxproj— add new files to project/test targetTest Plan
xcodebuild build -scheme SalesforceSDKCore -sdk iphonesimulator— succeedsSFOAuthErrorCodeTests— 6/6 passedSFOAuthCoordinatorLightningURLTests— 5/5 passedSalesforceSDKCoresuite — 706 tests, 0 failures