Skip to content

Error Handling

The CFC SDK handles all error-related messages automatically. You just provide callbacks in the config for the errors you want to react to.

Setup

typescript
import { CfcClient, Environment, IntegrationMode } from "@melio-eng/cfc-sdk";

const client = new CfcClient({
	container: document.getElementById("cfc-container")!,
	environment: Environment.STAGING,
	token: authToken,
	tenant: "my-tenant",
	mode: IntegrationMode.FULL_PAGE,

	onAuthenticationError: (reason, message) => {
		console.error(`Auth error [${reason}]: ${message}`);
	},
	onSessionExpired: () => {
		console.warn("Session expired");
	},
	onExitRequested: (originator) => {
		console.log(`Exit requested by: ${originator}`);
	},
	onError: (error) => {
		// SDK-level errors (e.g., sending message before init)
		console.error("SDK error:", error.message);
	},
});

client.init();

Authentication Errors

CFC emits AUTHENTICATION_ERROR when it cannot authenticate the provided token. The reason field indicates the specific failure:

AuthErrorReason Reference

ReasonDescriptionRecommended Action
EXPIRED_TOKENThe auth token has expiredRefresh the token and reinitialize
INVALID_TOKENThe token is malformed or has an invalid signatureCheck token generation logic
MISSING_TOKENNo token was provided in the auth URLEnsure token is set in config
BAD_RESPONSEThe auth endpoint returned an unexpected responseCheck server-side auth configuration
SERVICE_UNREACHABLEThe CFC auth service is not reachableRetry after a delay; check network connectivity
TENANT_NOT_FOUNDThe specified tenant does not existVerify the tenant value in configuration
UNEXPECTED_ERRORAn unclassified error occurredLog details and contact support

Handling Authentication Errors

typescript
const client = new CfcClient({
	// ...
	onAuthenticationError: (reason, message) => {
		switch (reason) {
			case "EXPIRED_TOKEN":
				// init() automatically cleans up the previous instance
				const newToken = await refreshToken();
				initCfc(newToken);
				break;

			case "INVALID_TOKEN":
			case "MISSING_TOKEN":
				window.location.href = "/login?error=invalid_token";
				break;

			case "SERVICE_UNREACHABLE":
				showRetryUI();
				break;

			case "TENANT_NOT_FOUND":
				showError("Tenant not found. Contact support.");
				break;

			default:
				showError(`Authentication failed: ${message}`);
		}
	},
});

Session Expiration

CFC emits SESSION_EXPIRED when the user's session within the iframe has expired. The host should re-authenticate:

typescript
const client = new CfcClient({
	// ...
	onSessionExpired: () => {
		client.destroy();

		// Option 1: Silent re-auth
		const freshToken = await refreshToken();
		initCfc(freshToken);

		// Option 2: Redirect to login
		window.location.href = "/login?reason=session_expired";
	},
});

Exit Requests

CFC emits EXIT_REQUESTED when the user wants to leave the CFC experience (e.g., clicking a "back" or "close" button within CFC):

typescript
const client = new CfcClient({
	// ...
	onExitRequested: (originator) => {
		console.log(`Exit requested by: ${originator}`);
		client.destroy();
		window.location.href = "/dashboard";
	},
});

Advanced: Low-Level Message Access

For advanced use cases, you can also listen to raw messages using the on method or the onMessage callback:

typescript
// Using the on method
client.on("AUTHENTICATION_ERROR", (msg) => {
	console.log(msg.reason, msg.message);
});

// Using the onMessage callback (receives all CFC messages)
const client = new CfcClient({
	// ...
	onMessage: (message) => {
		console.log("Raw CFC message:", message.type, message);
	},
});

SDK-Level Errors

The onError callback catches SDK internal errors (e.g., attempting to send a message before the iframe is initialized):

typescript
const client = new CfcClient({
	// ...
	onError: (error) => {
		console.error("SDK error:", error.message);
		errorReporting.capture(error);
	},
});

This is separate from CFC protocol errors (AUTHENTICATION_ERROR, SESSION_EXPIRED) and covers SDK internal failures.