Handle errors
Error model
Rejected promises and the error event carry a NablaConnectError with a stable code and an optional reason. Branch on code.
createthrows aTypeErrorwhen the iframe does not belong to a window. Nothing else throws.- The
errorevent is aNablaConnectErrorEvent, aCustomEventwith the error ondetail. It fires for an error afterreadythat no command owns, likeCONTEXT_CHANGED. - Failures before
readyrejectreadyonly. A rejectedreadyends the client: create another one to retry.TIMEOUTis the exception, see below. - After a
readyTIMEOUT, a failure that ends the client arrives on theerrorevent, sincereadyalready settled. - After
ready, an unexpected failure inside the SDK is anUNKNOWNerror event, and the client keeps running.
Error codes
COMMAND_REJECTED
The iframe refused or failed the command. reason is NOT_ALLOWED, STALE_STATE, INVALID_SESSION, EXPORT_FAILED, or UNKNOWN (an unexpected failure while running it). Re-read getCurrentState() and retry if the command is still allowed.
BUSY
The iframe cannot run the command right now: another command is running, the encounter is changing state, or the provider is busy in Nabla, for example during their first session. Wait for the next stateChanged.
TIMEOUT
No answer in 30 seconds.
- On
ready: usually a setup problem, see Troubleshooting. The client keeps listening, and a late first state arrives onstateChanged. Commands called before it reject withTIMEOUT. - On a command:
reasonisNO_RESULT. The outcome is unknown, not failed. See Timeouts.
CONTEXT_CHANGED
Another client was created on the same iframe, or another page loaded in it. Call destroy() and create a new client. A reload of the iframe does not cause it: the client reconnects.
UNSUPPORTED_VERSION
This SDK version cannot talk to the current iframe. Upgrade @nabla/connect-sdk.
INVALID_ORIGIN
The url you passed to create is not a Nabla Connect encounter URL. Pass the URL from your backend unchanged.
INVALID_MESSAGE
The iframe could not read a command. The error arrives on the command's promise, or on the error event when no command can be matched. Report it to connect@nabla.com.
DESTROYED
destroy() was called. Nothing to do.
UNKNOWN
The iframe sent something this SDK version does not understand (upgrade @nabla/connect-sdk), or an unexpected failure happened. After ready, the client keeps running: read the state before you retry a command.
Troubleshooting
ready rejects with TIMEOUT
The iframe sent no state within 30 seconds. Check, in this order:
- Nabla enabled the SDK for your organization, and your origin shows in the allowlist of Nabla Connect Admin. Nabla Connect Admin shows whether the front integration and the SDK are on.
POST /encounterswas called withtarget_origin, and it equals the origin of the page that embeds the iframe. When it is missing, the iframe console logs a warning.- That origin is in the allowlist, with the same scheme, hostname, and port.
- The
urlyou passed tocreateis an encounter URL, not a settings URL. Checkiframe.srcand the network tab. - No intermediate frame sits between your page and the iframe.
The client keeps listening after this rejection. If the state comes late, it arrives on stateChanged.
A new provider's first session
The first time a provider opens Nabla, the iframe signs them in and shows the Nabla onboarding over the encounter. The provider completes it in the iframe.
- The first state arrives within seconds, and
readyresolves. It is the real state, usuallyNOT_STARTED, with an emptyavailableActions. - Until the onboarding is over, commands reject with
BUSY. - When it is over, a
stateChangedbrings the available actions.
To handle it:
- Keep the iframe visible. The provider needs it to finish the onboarding.
- Enable your controls from
availableActionsonly. A command sent only when its action is listed does not get thisBUSY. - Do not start recording as soon as
readyresolves. To start it automatically, wait for the firststateChangedthat listsSTART_RECORDING. - Keep the client. It receives the actions on its own, so do not destroy it and create a new one.
A command rejects with TIMEOUT
The iframe did not answer within 30 seconds. This does not mean the command failed: see Timeouts.
- Read
stateChangedorgetCurrentState()to learn the outcome. The new state arrives when the command ends. - A new command before then rejects with
BUSY.