Skip to content

Commit

Permalink
feat: better error handling for registerTagEvent path (#396)
Browse files Browse the repository at this point in the history
  • Loading branch information
whitedogg13 authored May 15, 2021
1 parent c7eeb99 commit b6c3b0d
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 109 deletions.
47 changes: 24 additions & 23 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ declare module 'react-native-nfc-manager' {
}

type OnDiscoverTag = (evt: TagEvent) => void;
type OnSessionClosed = (evt: {}) => void;
type OnSessionClosed = (error?: NfcError.NfcErrorBase) => void;
type OnStateChanged = (evt: {state: string}) => void;
type OnNfcEvents = OnDiscoverTag | OnSessionClosed | OnStateChanged;

Expand Down Expand Up @@ -364,32 +364,33 @@ declare module 'react-native-nfc-manager' {
}

export namespace NfcError {
export class UnsupportedFeature extends Error {}
export class SecurityViolation extends Error {}
export class InvalidParameter extends Error {}
export class InvalidParameterLength extends Error {}
export class ParameterOutOfBound extends Error {}
export class RadioDisabled extends Error {}
export class NfcErrorBase extends Error {}
export class UnsupportedFeature extends NfcErrorBase {}
export class SecurityViolation extends NfcErrorBase {}
export class InvalidParameter extends NfcErrorBase {}
export class InvalidParameterLength extends NfcErrorBase {}
export class ParameterOutOfBound extends NfcErrorBase {}
export class RadioDisabled extends NfcErrorBase {}
// transceive errors
export class TagConnectionLost extends Error {}
export class RetryExceeded extends Error {}
export class TagResponseError extends Error {}
export class SessionInvalidated extends Error {}
export class TagNotConnected extends Error {}
export class PacketTooLong extends Error {}
export class TagConnectionLost extends NfcErrorBase {}
export class RetryExceeded extends NfcErrorBase {}
export class TagResponseNfcErrorBase extends Error {}
export class SessionInvalidated extends NfcErrorBase {}
export class TagNotConnected extends NfcErrorBase {}
export class PacketTooLong extends NfcErrorBase {}
// reader session errors
export class UserCancel extends Error {}
export class Timeout extends Error {}
export class Unexpected extends Error {}
export class SystemBusy extends Error {}
export class FirstNdefInvalid extends Error {}
export class UserCancel extends NfcErrorBase {}
export class Timeout extends NfcErrorBase {}
export class Unexpected extends NfcErrorBase {}
export class SystemBusy extends NfcErrorBase {}
export class FirstNdefInvalid extends NfcErrorBase {}
// tag command configuration errors
export class InvalidConfiguration extends Error {}
export class InvalidConfiguration extends NfcErrorBase {}
// ndef reader session error
export class TagNotWritable extends Error {}
export class TagUpdateFailure extends Error {}
export class TagSizeTooSmall extends Error {}
export class ZeroLengthMessage extends Error {
export class TagNotWritable extends NfcErrorBase {}
export class TagUpdateFailure extends NfcErrorBase {}
export class TagSizeTooSmall extends NfcErrorBase {}
export class ZeroLengthMessage extends NfcErrorBase {}
}
}

Expand Down
4 changes: 2 additions & 2 deletions ios/NfcManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ - (void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NS
NSLog(@"readerSession:didInvalidateWithError: (%@)", [error localizedDescription]);
[self reset];
[self sendEventWithName:@"NfcManagerSessionClosed"
body:@{}];
body:@{@"error": getErrorMessage(error)}];
}

- (void)tagReaderSession:(NFCTagReaderSession *)session didDetectTags:(NSArray<__kindof id<NFCTag>> *)tags
Expand Down Expand Up @@ -240,7 +240,7 @@ - (void)tagReaderSession:(NFCTagReaderSession *)session didInvalidateWithError:(

[self reset];
[self sendEventWithName:@"NfcManagerSessionClosed"
body:@{}];
body:@{@"error": getErrorMessage(error)}];
}

- (void)tagReaderSessionDidBecomeActive:(NFCTagReaderSession *)session
Expand Down
165 changes: 84 additions & 81 deletions src/NfcError.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import {Platform} from 'react-native';

export class UnsupportedFeature extends Error {}
export class SecurityViolation extends Error {}
export class InvalidParameter extends Error {}
export class InvalidParameterLength extends Error {}
export class ParameterOutOfBound extends Error {}
export class RadioDisabled extends Error {}
export class NfcErrorBase extends Error {}
export class UnsupportedFeature extends NfcErrorBase {}
export class SecurityViolation extends NfcErrorBase {}
export class InvalidParameter extends NfcErrorBase {}
export class InvalidParameterLength extends NfcErrorBase {}
export class ParameterOutOfBound extends NfcErrorBase {}
export class RadioDisabled extends NfcErrorBase {}
// transceive errors
export class TagConnectionLost extends Error {}
export class RetryExceeded extends Error {}
export class TagResponseError extends Error {}
export class SessionInvalidated extends Error {}
export class TagNotConnected extends Error {}
export class PacketTooLong extends Error {}
export class TagConnectionLost extends NfcErrorBase {}
export class RetryExceeded extends NfcErrorBase {}
export class TagResponseNfcErrorBase extends Error {}
export class SessionInvalidated extends NfcErrorBase {}
export class TagNotConnected extends NfcErrorBase {}
export class PacketTooLong extends NfcErrorBase {}
// reader session errors
export class UserCancel extends Error {}
export class Timeout extends Error {}
export class Unexpected extends Error {}
export class SystemBusy extends Error {}
export class FirstNdefInvalid extends Error {}
export class UserCancel extends NfcErrorBase {}
export class Timeout extends NfcErrorBase {}
export class Unexpected extends NfcErrorBase {}
export class SystemBusy extends NfcErrorBase {}
export class FirstNdefInvalid extends NfcErrorBase {}
// tag command configuration errors
export class InvalidConfiguration extends Error {}
export class InvalidConfiguration extends NfcErrorBase {}
// ndef reader session error
export class TagNotWritable extends Error {}
export class TagUpdateFailure extends Error {}
export class TagSizeTooSmall extends Error {}
export class ZeroLengthMessage extends Error {}
export class TagNotWritable extends NfcErrorBase {}
export class TagUpdateFailure extends NfcErrorBase {}
export class TagSizeTooSmall extends NfcErrorBase {}
export class ZeroLengthMessage extends NfcErrorBase {}

export const NfcErrorIOS = {
errCodes: {
Expand Down Expand Up @@ -78,71 +79,67 @@ export const NfcErrorIOS = {
};

export function buildNfcExceptionIOS(error) {
if (typeof error === 'string') {
const [domainError] = error.split(',');
const [domainError] = error.split(',');

if (domainError) {
const [nfcError, nfcErrorCode] = domainError.split(':');
if (nfcError === 'NFCError') {
const code = parseInt(nfcErrorCode, 10);
if (code === NfcErrorIOS.errCodes.unsupportedFeature) {
return new UnsupportedFeature();
} else if (code === NfcErrorIOS.errCodes.securityViolation) {
return new SecurityViolation();
} else if (code === NfcErrorIOS.errCodes.invalidParameter) {
return new InvalidParameter();
} else if (code === NfcErrorIOS.errCodes.invalidParameterLength) {
return new InvalidParameterLength();
} else if (code === NfcErrorIOS.errCodes.parameterOutOfBound) {
return new ParameterOutOfBound();
} else if (code === NfcErrorIOS.errCodes.tagConnectionLost) {
return new TagConnectionLost();
} else if (code === NfcErrorIOS.errCodes.retryExceeded) {
return new RetryExceeded();
} else if (code === NfcErrorIOS.errCodes.tagResponseError) {
return new TagResponseError();
} else if (code === NfcErrorIOS.errCodes.sessionInvalidated) {
return new SessionInvalidated();
} else if (code === NfcErrorIOS.errCodes.tagNotConnected) {
return new TagNotConnected();
} else if (code === NfcErrorIOS.errCodes.packetTooLong) {
return new PacketTooLong();
} else if (code === NfcErrorIOS.errCodes.userCancel) {
return new UserCancel();
} else if (code === NfcErrorIOS.errCodes.timeout) {
return new Timeout();
} else if (code === NfcErrorIOS.errCodes.unexpected) {
return new Unexpected();
} else if (code === NfcErrorIOS.errCodes.systemBusy) {
return new SystemBusy();
} else if (code === NfcErrorIOS.errCodes.firstNdefInvalid) {
return new FirstNdefInvalid();
} else if (code === NfcErrorIOS.errCodes.invalidConfiguration) {
return new InvalidConfiguration();
} else if (code === NfcErrorIOS.errCodes.tagNotWritable) {
return new TagNotWritable();
} else if (code === NfcErrorIOS.errCodes.tagUpdateFailure) {
return new TagUpdateFailure();
} else if (code === NfcErrorIOS.errCodes.tagSizeTooSmall) {
return new TagSizeTooSmall();
} else if (code === NfcErrorIOS.errCodes.zeroLengthMessage) {
return new ZeroLengthMessage();
}
if (domainError) {
const [nfcError, nfcErrorCode] = domainError.split(':');
if (nfcError === 'NFCError') {
const code = parseInt(nfcErrorCode, 10);
if (code === NfcErrorIOS.errCodes.unsupportedFeature) {
return new UnsupportedFeature();
} else if (code === NfcErrorIOS.errCodes.securityViolation) {
return new SecurityViolation();
} else if (code === NfcErrorIOS.errCodes.invalidParameter) {
return new InvalidParameter();
} else if (code === NfcErrorIOS.errCodes.invalidParameterLength) {
return new InvalidParameterLength();
} else if (code === NfcErrorIOS.errCodes.parameterOutOfBound) {
return new ParameterOutOfBound();
} else if (code === NfcErrorIOS.errCodes.tagConnectionLost) {
return new TagConnectionLost();
} else if (code === NfcErrorIOS.errCodes.retryExceeded) {
return new RetryExceeded();
} else if (code === NfcErrorIOS.errCodes.tagResponseError) {
return new TagResponseError();
} else if (code === NfcErrorIOS.errCodes.sessionInvalidated) {
return new SessionInvalidated();
} else if (code === NfcErrorIOS.errCodes.tagNotConnected) {
return new TagNotConnected();
} else if (code === NfcErrorIOS.errCodes.packetTooLong) {
return new PacketTooLong();
} else if (code === NfcErrorIOS.errCodes.userCancel) {
return new UserCancel();
} else if (code === NfcErrorIOS.errCodes.timeout) {
return new Timeout();
} else if (code === NfcErrorIOS.errCodes.unexpected) {
return new Unexpected();
} else if (code === NfcErrorIOS.errCodes.systemBusy) {
return new SystemBusy();
} else if (code === NfcErrorIOS.errCodes.firstNdefInvalid) {
return new FirstNdefInvalid();
} else if (code === NfcErrorIOS.errCodes.invalidConfiguration) {
return new InvalidConfiguration();
} else if (code === NfcErrorIOS.errCodes.tagNotWritable) {
return new TagNotWritable();
} else if (code === NfcErrorIOS.errCodes.tagUpdateFailure) {
return new TagUpdateFailure();
} else if (code === NfcErrorIOS.errCodes.tagSizeTooSmall) {
return new TagSizeTooSmall();
} else if (code === NfcErrorIOS.errCodes.zeroLengthMessage) {
return new ZeroLengthMessage();
}
}
}

return error;
return new NfcErrorBase(error);
}

export function buildNfcExceptionAndroid(error) {
if (typeof error === 'string') {
if (error === 'cancelled') {
return new UserCancel();
}
if (error === 'cancelled') {
return new UserCancel();
}

return error;
return new NfcErrorBase(error);
}

export async function handleNativeException(
Expand All @@ -153,11 +150,17 @@ export async function handleNativeException(
return await callNativePromise;
} catch (err) {
if (!ignoreError) {
if (Platform.OS === 'ios') {
throw buildNfcExceptionIOS(err);
} else if (Platform.OS === 'android') {
throw buildNfcExceptionAndroid(err);
// the error from the native side will always be a string
if (typeof err === 'string') {
if (Platform.OS === 'ios') {
throw buildNfcExceptionIOS(err);
} else if (Platform.OS === 'android') {
throw buildNfcExceptionAndroid(err);
}
}

// unexpected condition, simply throws them out without conversion
throw err;
}
}
}
11 changes: 8 additions & 3 deletions src/NfcManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import {
import {NdefHandler, NdefStatus} from './NfcTech/NdefHandler';
import {NfcAHandler} from './NfcTech/NfcAHandler';
import {IsoDepHandler} from './NfcTech/IsoDepHandler';
import {handleNativeException} from './NfcError';
import {
handleNativeException,
buildNfcExceptionIOS,
UserCancel,
} from './NfcError';

const NfcEvents = {
DiscoverTag: 'NfcManagerDiscoverTag',
Expand Down Expand Up @@ -145,10 +149,11 @@ class NfcManagerBase {
}
};

_onSessionClosedIOS = () => {
_onSessionClosedIOS = (resp) => {
const callback = this._clientListeners[NfcEvents.SessionClosed];
if (callback) {
callback();
const error = buildNfcExceptionIOS(resp.error);
callback(error instanceof UserCancel ? null : error);
}
};

Expand Down

0 comments on commit b6c3b0d

Please sign in to comment.