Skip to content

Commit

Permalink
[bugfix] add code and subcode to callError (#5672)
Browse files Browse the repository at this point in the history
* add code and subcode to error

* changelog

* Add call ended code and subcode

* update API file
  • Loading branch information
dmceachernmsft authored Feb 28, 2025
1 parent 893b40f commit a19b51c
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "minor",
"area": "fix",
"workstream": "Error handling",
"comment": "Add code and subcode to calling errors to help with debugging",
"packageName": "@azure/communication-react",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "minor",
"area": "fix",
"workstream": "Error handling",
"comment": "Add code and subcode to calling errors to help with debugging",
"packageName": "@azure/communication-react",
"email": "[email protected]",
"dependentChangeType": "patch"
}
20 changes: 18 additions & 2 deletions packages/calling-stateful-client/src/CallClientState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
ParticipantRole,
RemoteParticipantState as RemoteParticipantStatus,
ScalingMode,
VideoDeviceInfo
VideoDeviceInfo,
CommunicationServicesError
} from '@azure/communication-calling';
/* @conditional-compile-remove(breakout-rooms) */
import { BreakoutRoom, BreakoutRoomsSettings } from '@azure/communication-calling';
Expand Down Expand Up @@ -1118,15 +1119,30 @@ export class CallError extends Error {
* Timestamp added to the error by the stateful layer.
*/
public timestamp: Date;
/**
* Primary code for the calling error
*/
public code?: number;
/**
* Sub code for the calling error
*/
public subCode?: number;

/** needs to be a (innerError as CommunicationServicesError) */
constructor(target: CallErrorTarget, innerError: Error, timestamp?: Date) {
super();
this.target = target;
this.innerError = innerError;
if ('code' in (innerError as CommunicationServicesError)) {
this.code = (innerError as CommunicationServicesError).code;
}
if ('subCode' in (innerError as CommunicationServicesError)) {
this.subCode = (innerError as CommunicationServicesError).subCode;
}
// Testing note: It is easier to mock Date::now() than the Date() constructor.
this.timestamp = timestamp ?? new Date(Date.now());
this.name = 'CallError';
this.message = `${this.target}: ${this.innerError.message}`;
this.message = `${this.target}: ${this.innerError.message} code=${this.code} subCode=${this.subCode}`;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ export interface CallAdapter extends CommonCallAdapter {
// @public
export type CallAdapterCallEndedEvent = {
callId: string;
code?: number;
subCode?: number;
};

// @public @deprecated
Expand Down Expand Up @@ -1085,7 +1087,9 @@ export type CallEndedListener = (event: CallAdapterCallEndedEvent) => void;
// @public
export class CallError extends Error {
constructor(target: CallErrorTarget, innerError: Error, timestamp?: Date);
code?: number;
innerError: Error;
subCode?: number;
target: CallErrorTarget;
timestamp: Date;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export interface CallAdapter extends CommonCallAdapter {
// @public
export type CallAdapterCallEndedEvent = {
callId: string;
code?: number;
subCode?: number;
};

// @public @deprecated
Expand Down Expand Up @@ -899,7 +901,9 @@ export type CallEndedListener = (event: CallAdapterCallEndedEvent) => void;
// @public
export class CallError extends Error {
constructor(target: CallErrorTarget, innerError: Error, timestamp?: Date);
code?: number;
innerError: Error;
subCode?: number;
target: CallErrorTarget;
timestamp: Date;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,18 @@ class CallContext {
/* @conditional-compile-remove(unsupported-browser) */ environmentInfo
);
if (!IsCallEndedPage(oldPage) && IsCallEndedPage(newPage)) {
this.emitter.emit('callEnded', { callId: this.callId });
/**
* We want to make sure that the id of the call that is ending
* is the same as the call in the adapter as this is a scenario where
* the call has ended and not been transferred and report the codes for this call.
*/
if (this.callId === latestEndedCall?.id) {
this.emitter.emit('callEnded', {
callId: latestEndedCall?.id,
code: latestEndedCall?.callEndReason?.code,
subCode: latestEndedCall?.callEndReason?.subCode
});
}
// Reset the callId to undefined as the call has ended.
this.setCurrentCallId(undefined);
// Make sure that the call is set to undefined in the state.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export type DisplayNameChangedListener = (event: {
*
* @public
*/
export type CallAdapterCallEndedEvent = { callId: string };
export type CallAdapterCallEndedEvent = { callId: string; code?: number; subCode?: number };

/**
* Callback for {@link CallAdapterSubscribers} 'callEnded' event.
Expand Down
7 changes: 5 additions & 2 deletions samples/Calling/src/app/views/CallScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ export const CallScreen = (props: CallScreenProps): JSX.Element => {
console.log(`Call Id: ${callIdRef.current}`);
}
});
adapter.on('transferAccepted', (e) => {
console.log('Call being transferred to: ' + e);
adapter.on('transferAccepted', (event) => {
console.log('Call being transferred to: ' + event);
});
adapter.on('callEnded', (event) => {
console.log('Call ended id: ' + event.callId + ' code: ' + event.code, 'subcode: ' + event.subCode);
});
}, []);

Expand Down

0 comments on commit a19b51c

Please sign in to comment.