Error Handling
The Anyline Web SDK provides structured error handling through typed exceptions. Proper error handling ensures robust applications and better user experiences.
Exception Types
All SDK exceptions extend the base AnylineError class. Use instanceof checks to identify and handle specific error types:
import {
AnylineError,
CameraStreamError,
DisposedError,
LicenseParseError,
OnlyAndroidChromeError,
} from '@anyline/anyline-js';
try {
await anyline.startScanning();
} catch (error) {
if (error instanceof DisposedError) {
console.error('Cannot start scanning after dispose.');
} else if (error instanceof LicenseParseError) {
console.error('License error:', error.message);
} else if (error instanceof OnlyAndroidChromeError) {
console.warn('This feature is not supported on this browser.');
} else if (error instanceof AnylineError) {
console.error('SDK error:', error.message);
} else if (error instanceof DOMException && error.name === 'NotAllowedError') {
console.error('Browser blocked camera access:', error.message);
} else {
console.error('Unexpected error:', error);
}
}
Exception Types Reference
Initialization Errors
LicenseNotDefinedError
Thrown when the license key is not provided during SDK initialization.
Note: In most cases where a license is missing, undefined, or null, the SDK will throw LicenseParseError instead, as it attempts to parse the license value.
Solution:
// ❌ Wrong - no license
const anyline = init({
element: document.getElementById('root'),
preset: 'all_barcode_formats'
});
// ✅ Correct
const anyline = init({
license: 'YOUR_LICENSE_KEY',
element: document.getElementById('root'),
preset: 'all_barcode_formats'
});
LicenseParseError
Thrown when the license key format is invalid or corrupted, including when the license is missing, empty, undefined, or null.
Causes:
-
License is missing,
undefined,null, or empty string -
Malformed base64 string
-
Corrupted license JSON
-
Expired license
-
License doesn’t match domain/bundle ID
Solution:
try {
const anyline = init({
license: licenseKey,
element: document.getElementById('root'),
preset: 'all_barcode_formats'
});
} catch (error) {
if (error instanceof LicenseParseError) {
console.error('Invalid license format:', error.message);
// Contact support for a valid license
}
}
MountElementNotDefinedError
Thrown when the element passed to init() is invalid.
Causes:
-
Element is
nullorundefined -
Element ID doesn’t exist in DOM
-
init()called before DOM is ready
Solution:
// ✅ Validate element exists
const element = document.getElementById('scanner-root');
if (!element) {
throw new Error('Scanner container not found');
}
const anyline = init({
license: 'LICENSE',
element: element,
preset: 'all_barcode_formats'
});
MountError
Thrown when the SDK fails to mount its UI components to the DOM.
Causes:
-
Element already contains SDK instance
-
Element removed from DOM during initialization
-
CSS conflicts preventing rendering
-
Component unmounted during initialization (React/Vue)
Solution:
// Dispose previous instance before reinitializing
if (anylineInstance) {
anylineInstance.dispose();
}
const anyline = init({
license: 'LICENSE',
element: document.getElementById('root'),
preset: 'all_barcode_formats'
});
MediaDevicesError
Thrown when the browser cannot provide the MediaDevices API (either because the API is unavailable or because the page is not running in a secure context).
Cause: navigator.mediaDevices is missing or blocked. This typically happens on insecure origins (non-HTTPS/localhost) or on environments that do not implement the MediaDevices API.
Solution:
// Ensure secure origin OR an environment that exposes navigator.mediaDevices
if (!navigator.mediaDevices) {
throw new Error('Camera API is unavailable in this browser/context');
}
// Development: use localhost (automatically treated as secure)
// Production: always serve via HTTPS
if (location.protocol !== 'https:' && location.hostname !== 'localhost' && location.hostname !== '127.0.0.1') {
location.href = location.href.replace('http:', 'https:');
}
Configuration Errors
ConfigurationNotDefinedError
Thrown when no plugin configuration is provided with a valid preset and viewConfig.
Cause: The config parameter is missing or undefined when a valid preset is provided or when viewConfig.cutouts[].cutoutConfig exists but no plugin config is defined.
Note: If both preset and viewConfig.cutouts[].cutoutConfig are missing, CutoutConfigNotFoundError will be thrown first instead of this error.
Solution:
// ❌ Wrong - no config or preset
const anyline = init({
license: 'LICENSE',
element: root
// Missing both preset and config
});
// ✅ Option 1: Use preset
const anyline = init({
license: 'LICENSE',
element: root,
preset: 'all_barcode_formats'
});
// ✅ Option 2: Provide config with viewConfig
const anyline = init({
license: 'LICENSE',
element: root,
config: {
barcodeConfig: {
barcodeFormats: ['QR_CODE', 'CODE_128']
}
},
viewConfig: {
cutouts: [{
cutoutConfig: {
width: 720,
maxWidthPercent: '80%',
alignment: 'center'
}
}]
}
});
MultipleConfigTypesError
Thrown when more than one plugin configuration type is defined with a valid preset or viewConfig.
Cause: Only one config type is allowed per SDK instance (e.g., can’t have both barcodeConfig and meterConfig).
Note: If preset is not provided and viewConfig.cutouts[].cutoutConfig is missing, CutoutConfigNotFoundError will be thrown first instead of this error.
Solution:
// ❌ Wrong - multiple config types
const anyline = init({
license: 'LICENSE',
element: root,
preset: 'all_barcode_formats', // Need preset or viewConfig to reach this error
config: {
barcodeConfig: { barcodeFormats: ['QR_CODE'] },
meterConfig: { scanMode: 'AUTO' } // Can't have both!
}
});
// ✅ Correct - one config type
const anyline = init({
license: 'LICENSE',
element: root,
preset: 'all_barcode_formats',
config: {
barcodeConfig: { barcodeFormats: ['QR_CODE'] }
}
});
NoConfigTypeError
Thrown when the config object exists but contains no plugin configuration with a valid preset or viewConfig.
Cause: The config object is provided but doesn’t contain any recognized plugin config (like barcodeConfig, meterConfig, etc.).
Note: If preset is not provided and viewConfig.cutouts[].cutoutConfig is missing, CutoutConfigNotFoundError will be thrown first instead of this error.
Solution:
// ❌ Wrong - empty config without preset or viewConfig
const anyline = init({
license: 'LICENSE',
element: root,
config: {} // No plugin config!
});
// ✅ Correct - includes plugin config with viewConfig
const anyline = init({
license: 'LICENSE',
element: root,
config: {
barcodeConfig: {
barcodeFormats: ['QR_CODE']
}
},
viewConfig: {
cutouts: [{
cutoutConfig: {
width: 720,
alignment: 'center'
}
}]
}
});
InvalidConfigTypeError
Thrown when an unsupported or invalid configuration type is provided.
Cause: The config key doesn’t match any known plugin type.
Note: This error is rare in normal usage as TypeScript types prevent invalid config keys at compile time.
CutoutConfigNotFoundError
Thrown when using custom config without providing cutout configuration.
Cause: When using custom config (not preset), viewConfig.cutouts[].cutoutConfig is required.
Solution:
// ❌ Wrong - no cutoutConfig
const anyline = init({
license: 'LICENSE',
element: root,
config: {
barcodeConfig: { barcodeFormats: ['QR_CODE'] }
}
// Missing viewConfig!
});
// ✅ Correct - includes cutoutConfig
const anyline = init({
license: 'LICENSE',
element: root,
config: {
barcodeConfig: { barcodeFormats: ['QR_CODE'] }
},
viewConfig: {
cutouts: [{
cutoutConfig: {
width: 720,
maxWidthPercent: '80%',
alignment: 'center'
}
}]
}
});
PresetNotFoundError
Thrown when the specified preset name doesn’t exist.
Cause: Invalid preset name provided.
Solution:
// ❌ Wrong - invalid preset
const anyline = init({
license: 'LICENSE',
element: root,
preset: 'invalid_preset_name'
});
// ✅ Correct - valid preset
const anyline = init({
license: 'LICENSE',
element: root,
preset: 'all_barcode_formats' // Examples: 'all_barcode_formats', 'universalid_mrz', 'meter', 'lpt_eu', 'vin'
});
InvalidAlignmentError
Thrown when an invalid cutout alignment value is provided.
Cause: The alignment value in cutoutConfig is not one of the valid options.
Valid values: 'top', 'top_half', 'center', 'bottom_half', 'bottom'
Solution:
// ❌ Wrong - invalid alignment
viewConfig: {
cutouts: [{
cutoutConfig: {
width: 720,
alignment: 'invalid_value'
}
}]
}
// ✅ Correct
viewConfig: {
cutouts: [{
cutoutConfig: {
width: 720,
alignment: 'center'
}
}]
}
InvalidColorFormatError
Thrown when an invalid hex color format is provided for cutout styling.
Cause: Hex color strings must be exactly 6 or 8 characters (RGB or ARGB).
Solution:
// ❌ Wrong - invalid color formats
strokeColor: 'FFF' // Too short
strokeColor: '#FFFFFF' // Don't include '#'
strokeColor: 'FFFFFFFFF' // Too long
// ✅ Correct
strokeColor: 'FFFFFF' // 6 chars (RGB)
strokeColor: 'FF0099FF' // 8 chars (ARGB with alpha)
Operational Errors
DisposedError
Thrown when attempting to use the SDK after calling dispose().
Cause: All SDK methods become unavailable after disposal.
Solution:
// Check state before operations
import { State } from '@anyline/anyline-js';
if (anyline.getState() === State.DISPOSED) {
// Reinitialize
anyline = init({ /* ... */ });
}
await anyline.startScanning();
PreloadNotEnabledError
Thrown when calling preload() without enabling preload in config.
Cause: The preload: true option must be set during initialization to use preload().
Solution:
// ✅ Enable preload during init
const anyline = init({
license: 'LICENSE',
element: root,
preset: 'all_barcode_formats',
preload: true // Required!
});
// Now you can call preload()
await anyline.preload();
await anyline.startScanning();
NoActiveStreamError
Thrown when trying to stop scanning without an active camera stream.
Cause: stopScanning() called before startScanning() or after stream already stopped.
Solution:
// Check state before stopping
import { State } from '@anyline/anyline-js';
const state = anyline.getState();
if (state === State.SCANNING) {
await anyline.stopScanning();
}
NotMountedError
Thrown when the SDK is not mounted to the DOM yet.
Cause: Attempting operations before the SDK has completed mounting.
Solution: Wait for initialization to complete before calling SDK methods. The init() function returns immediately, but mounting happens asynchronously.
OnlyAndroidChromeError
Thrown when using features that require specific browser capabilities.
Affected features:
-
camera.refocus()- Manual camera refocus (Chrome for Android only) -
camera.activateFlash()- Flash control (Chrome for Android, Safari 18.4+) -
lockPortraitOrientation- Orientation locking (Chrome for Android only) -
landscapeOrientation- Landscape mode (Chrome for Android only)
Supported browsers for ImageCapture features:
-
✅ Chrome for Android
-
✅ Safari 18.4+ (iOS 18.4+)
-
❌ Desktop browsers
-
❌ Safari < 18.4
Solution:
// Feature detection
if (typeof ImageCapture !== 'undefined') {
try {
await anyline.camera.activateFlash(true);
} catch (error) {
if (error instanceof OnlyAndroidChromeError) {
console.log('Flash not available on this platform');
// Hide flash button in UI
}
}
}
NotScanningError
Thrown when an operation requires an active scanning session but none is running.
Cause: Attempting an operation that requires scanning to be active (e.g., pauseScanning()) when the SDK is not currently scanning.
Solution:
// Check state before pausing
import { State } from '@anyline/anyline-js';
const state = anyline.getState();
if (state === State.SCANNING) {
anyline.pauseScanning();
}
NotStoppedError
Thrown when an operation requires the SDK to be in stopped state but it is not.
Cause: Attempting an operation that requires scanning to be stopped first.
Solution:
// Ensure scanning is stopped before the operation
import { State } from '@anyline/anyline-js';
const state = anyline.getState();
if (state === State.SCANNING || state === State.PAUSED) {
await anyline.stopScanning();
}
CameraStreamError
Thrown when the camera stream cannot be established.
Causes:
-
Camera permissions denied by user
-
Camera in use by another application
-
Hardware camera error
-
No camera available on device
Solution:
try {
await anyline.startScanning();
} catch (error) {
if (error instanceof CameraStreamError) {
console.error('Failed to access camera:', error.message);
// Show user-friendly message about camera access
}
}
FeatureNotAvailableError
Thrown when attempting to use a feature that is not available with the current license or configuration.
Cause: The requested feature requires a different license tier or is not enabled for your account.
Solution: Contact your sales representative to enable the feature for your license.
See Also
-
API Reference - Complete API reference
-
Plugin Configuration - Configuration options
-
State Management - State management guide
-
Camera API - Camera API documentation
-
Getting Started - Getting started guide