CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tinify

Node.js client for the Tinify API that intelligently compresses, resizes, converts, and stores images in AVIF, WebP, JPEG, and PNG formats.

Pending
Overview
Eval results
Files

error-handling.mddocs/

Error Handling

Comprehensive error types for different failure scenarios including authentication, client, server, and connection errors.

Capabilities

Error Class Hierarchy

Tinify provides a structured error hierarchy for different types of failures.

/**
 * Base error class for all Tinify errors
 */
class Error extends globalThis.Error {
  /** HTTP status code if available */
  status?: number;
  
  /**
   * Create a new Tinify error
   * @param message - Error message
   * @param type - Error type string
   * @param status - HTTP status code
   */
  constructor(message: string, type?: string, status?: number);
  
  /**
   * Factory method to create appropriate error subclass
   * @param message - Error message
   * @param type - Error type from API
   * @param status - HTTP status code
   * @returns Appropriate error subclass instance
   */
  static create(message: string, type: string, status?: number): Error;
}

/**
 * Account-related errors (authentication, billing, limits)
 * Thrown for HTTP status codes 401 and 429
 */
class AccountError extends Error {}

/**
 * Client-side errors (invalid input, bad requests)
 * Thrown for HTTP status codes 400-499 (except 401, 429)
 */
class ClientError extends Error {}

/**
 * Server-side errors (API service issues)
 * Thrown for HTTP status codes 500-599
 */
class ServerError extends Error {}

/**
 * Network connectivity errors
 * Thrown for connection failures, timeouts, proxy issues
 */
class ConnectionError extends Error {}

Account Errors

Handle authentication, billing, and API usage limit issues.

Common Account Error Scenarios:

  • Invalid or missing API key
  • Monthly compression limit exceeded
  • Account suspension or billing issues
  • Rate limiting (too many requests)

Usage Examples:

const tinify = require("tinify");

// Invalid API key
tinify.key = "invalid-key";

try {
  await tinify.fromFile("image.jpg").toFile("compressed.jpg");
} catch (error) {
  if (error instanceof tinify.AccountError) {
    if (error.status === 401) {
      console.error("Invalid API key:", error.message);
      // Prompt user to check their API key
    } else if (error.status === 429) {
      console.error("Monthly limit exceeded:", error.message);
      // Handle billing upgrade or wait for next month
    }
  }
}

// Check compression count to avoid limits
tinify.key = "valid-api-key";

try {
  await tinify.validate();
  console.log(`Compressions used: ${tinify.compressionCount}`);
  
  if (tinify.compressionCount && tinify.compressionCount > 450) {
    console.warn("Approaching monthly limit!");
  }
} catch (error) {
  if (error instanceof tinify.AccountError) {
    console.error("Account validation failed:", error.message);
  }
}

Client Errors

Handle invalid input, unsupported formats, and malformed requests.

Common Client Error Scenarios:

  • Invalid file format or corrupted image
  • Unsupported transformation parameters
  • Invalid URLs or file paths
  • Malformed configuration options

Usage Examples:

const tinify = require("tinify");

tinify.key = "your-api-key";

try {
  // Invalid file path
  await tinify.fromFile("nonexistent-file.jpg").toFile("output.jpg");
} catch (error) {
  if (error instanceof tinify.ClientError) {
    console.error("Client error:", error.message);
    
    if (error.status === 400) {
      console.error("Bad request - check input parameters");
    } else if (error.status === 415) {
      console.error("Unsupported image format");
    }
  }
}

try {
  // Invalid transformation options
  await tinify.fromFile("image.jpg")
    .resize({ method: "invalid-method", width: -100 })
    .toFile("output.jpg");
} catch (error) {
  if (error instanceof tinify.ClientError) {
    console.error("Invalid resize options:", error.message);
  }
}

try {
  // Invalid URL
  await tinify.fromUrl("not-a-valid-url").toFile("output.jpg");
} catch (error) {
  if (error instanceof tinify.ClientError) {
    console.error("Invalid URL provided:", error.message);
  }
}

Server Errors

Handle temporary API service issues and server-side problems.

Common Server Error Scenarios:

  • Temporary API service outages
  • Server overload or maintenance
  • Internal processing errors

Usage Examples:

const tinify = require("tinify");

tinify.key = "your-api-key";

try {
  await tinify.fromFile("image.jpg").toFile("compressed.jpg");
} catch (error) {
  if (error instanceof tinify.ServerError) {
    console.error("Server error:", error.message);
    
    if (error.status === 500) {
      console.error("Internal server error - try again later");
    } else if (error.status === 502 || error.status === 503) {
      console.error("Service temporarily unavailable");
    }
    
    // Implement retry logic for server errors
    setTimeout(async () => {
      try {
        await tinify.fromFile("image.jpg").toFile("compressed.jpg");
        console.log("Retry successful");
      } catch (retryError) {
        console.error("Retry failed:", retryError.message);
      }
    }, 5000);
  }
}

Connection Errors

Handle network connectivity, proxy, and timeout issues.

Common Connection Error Scenarios:

  • Network connectivity problems
  • Proxy configuration issues
  • Request timeouts
  • DNS resolution failures

Usage Examples:

const tinify = require("tinify");

tinify.key = "your-api-key";
tinify.proxy = "http://proxy.example.com:8080";

try {
  await tinify.fromFile("image.jpg").toFile("compressed.jpg");
} catch (error) {
  if (error instanceof tinify.ConnectionError) {
    console.error("Connection error:", error.message);
    
    // Check different potential causes
    if (error.message.includes("ENOTFOUND")) {
      console.error("DNS resolution failed - check network connectivity");
    } else if (error.message.includes("ECONNREFUSED")) {
      console.error("Connection refused - check proxy settings");
    } else if (error.message.includes("timeout")) {
      console.error("Request timeout - check network speed");
    }
    
    // Suggest troubleshooting steps
    console.log("Troubleshooting suggestions:");
    console.log("1. Check internet connectivity");
    console.log("2. Verify proxy settings");
    console.log("3. Try again without proxy");
    
    // Retry without proxy
    try {
      tinify.proxy = "";
      await tinify.fromFile("image.jpg").toFile("compressed.jpg");
      console.log("Success without proxy");
    } catch (retryError) {
      console.error("Still failing without proxy:", retryError.message);
    }
  }
}

Comprehensive Error Handling

Best practices for handling all error types in production applications.

Usage Example:

const tinify = require("tinify");

tinify.key = "your-api-key";

async function processImage(inputPath: string, outputPath: string, maxRetries = 3): Promise<boolean> {
  let retries = 0;
  
  while (retries < maxRetries) {
    try {
      await tinify.fromFile(inputPath)
        .resize({ method: "fit", width: 1200 })
        .toFile(outputPath);
      
      console.log(`Successfully processed: ${outputPath}`);
      return true;
      
    } catch (error) {
      if (error instanceof tinify.AccountError) {
        if (error.status === 401) {
          console.error("Invalid API key - check configuration");
          return false; // Don't retry for auth errors
        } else if (error.status === 429) {
          console.error("Monthly limit exceeded");
          return false; // Don't retry for limit errors
        }
        
      } else if (error instanceof tinify.ClientError) {
        console.error(`Client error: ${error.message}`);
        return false; // Don't retry for client errors
        
      } else if (error instanceof tinify.ServerError) {
        console.error(`Server error (attempt ${retries + 1}): ${error.message}`);
        retries++;
        
        if (retries < maxRetries) {
          const delay = Math.pow(2, retries) * 1000; // Exponential backoff
          console.log(`Retrying in ${delay}ms...`);
          await new Promise(resolve => setTimeout(resolve, delay));
        }
        
      } else if (error instanceof tinify.ConnectionError) {
        console.error(`Connection error (attempt ${retries + 1}): ${error.message}`);
        retries++;
        
        if (retries < maxRetries) {
          const delay = 2000; // Fixed delay for connection errors
          console.log(`Retrying in ${delay}ms...`);
          await new Promise(resolve => setTimeout(resolve, delay));
        }
        
      } else {
        console.error(`Unexpected error: ${error.message}`);
        return false;
      }
    }
  }
  
  console.error(`Failed to process image after ${maxRetries} attempts`);
  return false;
}

// Usage
const success = await processImage("input.jpg", "output.jpg");
if (!success) {
  console.error("Image processing failed permanently");
}

Error Status Codes

Common HTTP status codes and their corresponding error types:

Account Errors:

  • 401: Unauthorized (invalid API key)
  • 429: Too Many Requests (monthly limit exceeded)

Client Errors:

  • 400: Bad Request (invalid parameters)
  • 415: Unsupported Media Type (invalid image format)

Server Errors:

  • 500: Internal Server Error
  • 502: Bad Gateway
  • 503: Service Unavailable

Connection Errors:

  • No status code (network-level failures)

Error Inspection Example:

const tinify = require("tinify");

tinify.key = "your-api-key";

try {
  await tinify.fromFile("image.jpg").toFile("compressed.jpg");
} catch (error) {
  console.log(`Error type: ${error.constructor.name}`);
  console.log(`Error message: ${error.message}`);
  
  if (error.status) {
    console.log(`HTTP status: ${error.status}`);
  }
  
  // Type-specific handling
  switch (error.constructor.name) {
    case 'AccountError':
      console.log("Account-related issue");
      break;
    case 'ClientError':
      console.log("Client-side issue");
      break;
    case 'ServerError':
      console.log("Server-side issue");
      break;
    case 'ConnectionError':
      console.log("Network connectivity issue");
      break;
    default:
      console.log("Unknown error type");
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-tinify

docs

cloud-storage.md

configuration.md

error-handling.md

image-sources.md

index.md

results.md

transformations.md

tile.json