Skip to main content

Videoagreement Error Codes

The Videoagreement module captures video recordings of users reading and agreeing to terms or statements. When errors occur, they are thrown as ResponseError objects with specific error codes.

Error Structure

All errors follow the ResponseError structure:
interface ResponseError {
  code: string;        // Error code constant
  message: string;     // Human-readable error message
  details?: any;       // Optional additional error details
}

Error Codes

NOT_ACCEPT_CAMERA_PERMISSION

Thrown when the user denies camera permissions or camera access is not available. Code: FadSDK.Errors.Videoagreement.NOT_ACCEPT_CAMERA_PERMISSION When it occurs:
  • User explicitly denies camera permission
  • Camera permissions blocked by browser or system settings
  • Camera is already in use by another application
  • Camera hardware is not available or malfunctioning
  • Browser doesn’t support camera access (missing MediaDevices API)
How to handle:
try {
  const LEGEND = 'I, [Name], with date of birth [DOB], hereby declare that the information provided is true and accurate.';
  
  const videoagreementResponse = await FAD_SDK.startVideoagreement(
    LEGEND,
    CONFIGURATION
  );

  if (videoagreementResponse.event === FadSDK.Constants.EventModule.MODULE_CLOSED) {
    console.log('Module closed by user');
    return;
  }

  // Process video agreement
  const videoUrl = URL.createObjectURL(videoagreementResponse.data.video);
  console.log('Video agreement captured:', videoUrl);
  
} catch (ex) {
  if (ex.code === FadSDK.Errors.Videoagreement.NOT_ACCEPT_CAMERA_PERMISSION) {
    alert('Camera permission is required to record your agreement. Please enable camera access.');
    // Provide instructions for enabling camera
  }
}
The Videoagreement module requires camera access to record the user reading the agreement. Without camera permissions, the module cannot function.

Complete Error Handling Example

import FadSDK from '@fad-producto/fad-sdk';

async function recordVideoAgreement() {
  const FAD_SDK = new FadSDK(TOKEN, {
    environment: FadSDK.getFadEnvironments().UATHA
  });

  try {
    // Define the agreement text the user will read
    const LEGEND = `
      I, [Full Name], with date of birth [DOB], 
      with ID number [ID_NUMBER] declare that I am [Marital Status], 
      with monthly income of $[Amount], 
      I [do/do not] own a home, 
      I [do/do not] currently have credit cards, 
      and I acknowledge that the information I have provided is true and accurate.
    `;

    const videoagreementResponse = await FAD_SDK.startVideoagreement(
      LEGEND,
      CONFIGURATION
    );

    // Check if user closed the module
    if (videoagreementResponse.event === FadSDK.Constants.EventModule.MODULE_CLOSED) {
      console.log('User closed the video agreement module');
      return;
    }

    // Process successful video agreement capture
    console.log('Video agreement captured successfully');

    // Create URL for video playback
    const videoUrl = URL.createObjectURL(videoagreementResponse.data.video);

    // Display video
    const videoElement = document.getElementById('video-id') as HTMLVideoElement;
    const downloadLink = document.getElementById('download-link') as HTMLAnchorElement;

    videoElement.src = videoUrl;
    downloadLink.href = videoUrl;
    downloadLink.download = 'video-agreement.webm';

    console.log('Video agreement ready for playback');

  } catch (ex) {
    console.error('Videoagreement error:', ex);

    if (ex.code === FadSDK.Errors.Videoagreement.NOT_ACCEPT_CAMERA_PERMISSION) {
      alert('Camera access is required to record your agreement. Please enable camera permissions and try again.');
      // Show instructions for enabling camera
      showCameraPermissionInstructions();
    } else {
      // Handle unexpected errors
      console.error('Unexpected error:', ex);
      alert(`An error occurred: ${ex.message}`);
    }
  } finally {
    FAD_SDK.end();
  }
}

function showCameraPermissionInstructions() {
  const instructions = `
    To enable camera access:
    1. Click the camera icon in your browser's address bar
    2. Select 'Allow' for camera access
    3. Reload the page and try again
  `;
  console.log(instructions);
}

Response Data Structure

When successful, the Videoagreement module returns:
interface VideoagreementResponse {
  data: {
    video: Blob;           // Video recording of user reading the agreement
    duration?: number;     // Duration of the recording in seconds
    timestamp?: string;    // ISO timestamp of when recording was completed
  };
  event: string;           // Event type (PROCESS_COMPLETED, MODULE_CLOSED)
}

Legend Text Guidelines

The legend (agreement text) should be:

Clear & Concise

Use simple language that’s easy to read aloud

Appropriately Sized

Not too long - user should be able to read it in 30-60 seconds

Well Formatted

Break into readable segments with proper punctuation

Personalized

Include placeholders for user-specific information

Camera Permission Flow

1

Request Permission

When startVideoagreement() is called, the browser prompts for camera access.
2

User Decision

User either grants or denies camera permission.
3

Permission Granted

Module displays the legend text and begins recording when user is ready.
4

Permission Denied

NOT_ACCEPT_CAMERA_PERMISSION error is thrown if denied.

Error Recovery Strategies

Check camera permissions before starting the module:
async function checkCameraAccess(): Promise<boolean> {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ 
      video: true, 
      audio: false 
    });
    
    // Stop all tracks immediately
    stream.getTracks().forEach(track => track.stop());
    
    return true;
  } catch (error) {
    console.error('Camera access check failed:', error);
    return false;
  }
}

async function initVideoAgreement() {
  const hasCamera = await checkCameraAccess();
  
  if (!hasCamera) {
    alert('Please enable camera access to record your agreement');
    showCameraPermissionInstructions();
    return;
  }
  
  // Proceed with video agreement
  await recordVideoAgreement();
}
Provide platform-specific guidance:
function getCameraInstructions(): string {
  const userAgent = navigator.userAgent.toLowerCase();
  
  if (userAgent.includes('chrome')) {
    return 'Click the camera icon in the address bar and select "Allow"';
  } else if (userAgent.includes('firefox')) {
    return 'Click the permissions icon and enable camera access';
  } else if (userAgent.includes('safari')) {
    return 'Go to Safari > Settings > Camera and allow access for this website';
  } else if (userAgent.includes('edge')) {
    return 'Click the lock icon in the address bar and enable camera';
  }
  
  return 'Please enable camera permissions in your browser settings';
}
Query current permission state:
async function getCameraPermissionState(): Promise<PermissionState> {
  try {
    const result = await navigator.permissions.query({ 
      name: 'camera' as PermissionName 
    });
    return result.state; // 'granted', 'denied', or 'prompt'
  } catch (error) {
    console.error('Permission query not supported:', error);
    return 'prompt';
  }
}

async function handleVideoAgreement() {
  const state = await getCameraPermissionState();
  
  if (state === 'denied') {
    alert('Camera access is blocked. Please update your browser settings.');
    showCameraPermissionInstructions();
    return;
  } else if (state === 'prompt') {
    // Show explanation before requesting permission
    showCameraPermissionRationale();
  }
  
  await recordVideoAgreement();
}

function showCameraPermissionRationale() {
  alert('We need camera access to record you reading the agreement. This ensures the authenticity of your consent.');
}

Best Practices

Explain Purpose

Before requesting camera access, explain why video recording is necessary for the agreement process.

Preview Legend

Show users the legend text before starting the recording so they can prepare.

Practice Run

Consider offering a practice mode where users can rehearse reading the agreement without recording.

Clear Instructions

Provide step-by-step guidance on how to position themselves and speak clearly during recording.

Retry Option

Always allow users to retry if they’re not satisfied with their recording.

Module Closure Events

The Videoagreement module can be closed by the user at any time:
if (videoagreementResponse.event === FadSDK.Constants.EventModule.MODULE_CLOSED) {
  // User cancelled the video agreement process
  console.log('Video agreement cancelled by user');
  // Handle cancellation gracefully
}
Module closure is not an error condition - it’s a normal user action. Handle it gracefully by allowing users to restart or exit the flow.

Video Storage and Processing

Video files can be large. Consider:
  • Compressing videos before upload
  • Implementing progress indicators for uploads
  • Providing video quality options if bandwidth is limited
  • Setting appropriate timeout values for slow connections

Build docs developers (and LLMs) love