SIP.js
SIP.js copied to clipboard
Inviter Cancel cause error
I am trying to cancel the call on establishing state. This is my code:
const currentState = this.session.state; switch (currentState) { case SessionState.Initial: case SessionState.Establishing: // An unestablished outgoing session this.session.cancel(); break; case SessionState.Established: // An established session this.session.bye(); break; case SessionState.Terminating: case SessionState.Terminated: // Cannot terminate a session that is already terminated break; default: break;
This is the error I received:
Mon Oct 04 2021 15:33:37 GMT-0700 (Pacific Daylight Time) | sip.Inviter | Session ou7thehijqam4ovcb4nhe5t3t1en0n in state Terminated is being disposed logger-factory.js:93 Mon Oct 04 2021 15:33:41 GMT-0700 (Pacific Daylight Time) | sip.SessionDescriptionHandler | SessionDescriptionHandler.getDescription failed - Error: Peer connection closed. index.js:1 Mon Oct 04 2021 15:33:41 GMT-0700 (Pacific Daylight Time) | sip.Inviter | Session.getOffer: SDH getDescription rejected... index.js:1 Mon Oct 04 2021 15:33:41 GMT-0700 (Pacific Daylight Time) | sip.Inviter | Peer connection closed. index.js:1 Mon Oct 04 2021 15:33:41 GMT-0700 (Pacific Daylight Time) | sip.Inviter | Peer connection closed. logger-factory.js:93 Uncaught (in promise) Error: Invalid state transition from Terminated to Terminated invalidTransition session.js:1139 stateTransition session.js:1169 invite inviter.js:348 promise callback*invite inviter.js:345 call webphone.js:398 call NewCallKeypad.jsx:32 React 14 unstable_runWithPriority scheduler.development.js:468 React 15 js index.js:14 js main.chunk.js:15396 Webpack 7
I tried to add this listener:
this.session.stateChange.addListener((state) => { switch (state) { case SessionState.Initial: break; case SessionState.Establishing: console.log('>>>>Tri------Connecting: '); break; case SessionState.Established: console.log('>>>>Tri------Connected: '); break; case SessionState.Terminating: // fall through case SessionState.Terminated: console.log('Tri-----Session Terminated') break; default: throw new Error('Unknown session state.'); } });
The listener showed that State Change change to Terminated twice. Can anyone please help me with this problem?
Thank you.
You are doing it correctly. Canceling the request on Establishing
state.
I think it would be better if you share a full console log including the SIP messages from when you start dialing out and until the very moment you're trying to cancel and getting the error.
I think the problem happens when I cancel the request on SessionState.Initial
I am also doing it on Initial
state, and I didn't observe any issues yet, nor our QA team that are awesome with trying to break things up heh.
It is strange that there's that error that session state is transitioned from Terminated
to Terminated
. Maybe if you'll share a full console log with the SIP messages and SIP.js logs it might clear things up. It'll help more to the developers of this project.
Hi guys, any follow-up on this? I'm having the same error when I start a call and cancel it straight away.
I am facing the same issue. Any update on this?
I'm hitting the same snag using the latest version of the library (0.20.0)
I think the problem happens when I cancel the request on SessionState.Initial
Yes, you need to end the call when the session state === Establishing, if the session has not yet been initialized or is in the Initial state, there will be an error.
inviter.invite() is calling getOffer() which is failing and throwing which is caught and results in a request to transition state to Terminated. But the session is already Terminated and so the request to transition is in turn throwing - that's a bug as we shouldn't be trying transition state to a state we are already in.
But as to cancelling triggering the getOffer() failure, will need to take closer look at how that could happen. Could have something to do with being in Initial state, but will need to take a closer look.
But fixed the double state transition to Terminated and the associated double error throwing here: f06939c119149a3e00ad8acf69f37360d3331a62
TL;DR - invite()
can reject with an Error and does so if cancel()
is called before the INVITE is actually sent (before the session transitions to state Establishing).
I believe the double throw may have been obscuring what is going on because it was eating an error message - so good to be rid of it. And I can explain what is going on.
With a plain old invite (without cancel being called) things look like this...
- invite() called
- session in Initial state
- getUserMedia() (and other async stuff) is called (down in session description handler)
- getUserMedia() (and other async stuff) resolves
- session transitions to Establishing
- invite() resolves
.invite()
is async and in the default case if .cancel()
is called before it resolves, the following sequence occurs...
- invite() called
- session in Initial state
- getUserMedia() (and other async stuff) is called (down in session description handler)
- cancel() called
- Warning
sip.Inviter | Canceled session before INVITE was sent
is logged - session transition to Terminated
- cancel() resolves
- session description handler disposed and associated peer connection closed
- getUserMedia() (and other async stuff) resolves
- session description handler throws because peer connection gone (or whatever else bad happened cause rug got pulled)
- invite() catches error and rejects
So, if you call invite() and don't wait for it to resolve (or alternatively wait for the session state transition to Establishing) and then call cancel() (or otherwise terminate the session in some fashion) you need to be prepared for invite() to reject.
The documentation for session description handler currently states - "Rejects with ClosedSessionDescriptionHandlerError
when this method is called after close or when close occurs before complete." - and a nice typed error like that would allow for nice clean rejection handling, but that's not implemented (yet) and for now one needs to just catch whatever generic Error on the invite promise rejecting and perhaps just log (or not) and move on.
Hope that makes sense? Assuming so will close this out shortly.