atp-sdk
Version:
Official TypeScript SDK for Agent Trust Protocol™ - Build secure, verifiable, and trustworthy applications with decentralized identity, verifiable credentials, and robust access control
850 lines (678 loc) • 20.2 kB
Markdown
# Troubleshooting Guide
This guide helps you diagnose and resolve common issues when using the ATP™ SDK.
## Table of Contents
1. [Common Issues](#common-issues)
2. [Connection Problems](#connection-problems)
3. [Authentication Issues](#authentication-issues)
4. [Performance Problems](#performance-problems)
5. [Error Messages](#error-messages)
6. [Debugging Tools](#debugging-tools)
7. [Getting Help](#getting-help)
## Common Issues
### SDK Installation Problems
**Issue: Package not found**
```bash
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@atp%2fsdk
```
**Solution:**
```bash
# Check if you have access to the ATP registry
npm config get registry
# If using private registry, ensure authentication
npm login --registry=https://npm.atp.example.com
# Verify package name and version
npm search @atp/sdk
```
**Issue: Version conflicts**
```bash
npm ERR! peer dep missing: @atp/sdk@^1.0.0
```
**Solution:**
```bash
# Check installed versions
npm ls @atp/sdk
# Update to compatible version
npm install @atp/sdk@^1.0.0
# Clear npm cache if needed
npm cache clean --force
```
### Import/Module Issues
**Issue: ES module import errors**
```javascript
SyntaxError: Cannot use import statement outside a module
```
**Solution:**
```javascript
// Option 1: Use ES modules in package.json
{
"type": "module"
}
// Option 2: Use CommonJS require
const { ATPClient } = require('@atp/sdk');
// Option 3: Use .mjs extension
// file: app.mjs
import { ATPClient } from '@atp/sdk';
```
**Issue: TypeScript compilation errors**
```typescript
TS2307: Cannot find module '@atp/sdk' or its corresponding type declarations
```
**Solution:**
```bash
# Install TypeScript types
npm install --save-dev @types/atp__sdk
# Or ensure TypeScript version compatibility
npm install typescript@^4.5.0
```
## Connection Problems
### Service Unavailable
**Issue: Cannot connect to ATP services**
```
ATPNetworkError: Connection refused (ECONNREFUSED)
```
**Diagnostic Steps:**
```javascript
// 1. Test basic connectivity
const client = new ATPClient(config);
const health = await client.testConnectivity();
console.log('Service status:', health);
// 2. Check individual services
try {
await client.identity.getHealth();
console.log('Identity service: OK');
} catch (error) {
console.error('Identity service error:', error.message);
}
// 3. Verify configuration
console.log('Config:', {
baseUrl: config.baseUrl,
services: config.services,
timeout: config.timeout
});
```
**Common Solutions:**
```javascript
// Check if services are running
const config = {
baseUrl: 'http://localhost',
services: {
identity: 'http://localhost:3001', // ✓ Correct port
credentials: 'http://localhost:3002', // ✓ Correct port
permissions: 'http://localhost:3003', // ✓ Correct port
audit: 'http://localhost:3004', // ✓ Correct port
gateway: 'http://localhost:3000' // ✓ Correct port
}
};
// Increase timeout for slow networks
const config = {
baseUrl: 'https://api.atp.example.com',
timeout: 60000, // 60 seconds
retries: 5,
retryDelay: 2000
};
```
### Network Timeouts
**Issue: Requests timing out**
```
ATPNetworkError: Request timeout (ETIMEDOUT)
```
**Diagnostic Script:**
```javascript
async function diagnoseNetwork() {
const startTime = Date.now();
try {
const response = await fetch(config.baseUrl + '/health', {
signal: AbortSignal.timeout(5000)
});
const duration = Date.now() - startTime;
console.log(`Network latency: ${duration}ms`);
if (duration > 10000) {
console.warn('High latency detected');
}
} catch (error) {
console.error('Network diagnostic failed:', error.message);
}
}
await diagnoseNetwork();
```
**Solutions:**
```javascript
// 1. Increase timeouts
const config = {
timeout: 30000, // 30 seconds
retries: 3,
retryDelay: 2000
};
// 2. Use different service endpoints
const config = {
services: {
identity: 'https://identity-backup.atp.example.com',
// ... other services
}
};
// 3. Implement circuit breaker
const circuitBreaker = new CircuitBreaker({
timeout: 10000,
errorThresholdPercentage: 50,
resetTimeout: 30000
});
```
### DNS Resolution Issues
**Issue: Cannot resolve hostname**
```
ATPNetworkError: getaddrinfo ENOTFOUND api.atp.example.com
```
**Diagnostic:**
```bash
# Test DNS resolution
nslookup api.atp.example.com
dig api.atp.example.com
# Check /etc/hosts file
cat /etc/hosts | grep atp
# Test with IP address
ping 192.168.1.100
```
**Solutions:**
```javascript
// 1. Use IP address directly
const config = {
baseUrl: 'https://192.168.1.100:3000'
};
// 2. Configure custom DNS
const config = {
dns: {
servers: ['8.8.8.8', '8.8.4.4']
}
};
// 3. Add to hosts file (temporary)
// echo "192.168.1.100 api.atp.example.com" >> /etc/hosts
```
## Authentication Issues
### Invalid DID Format
**Issue: DID validation fails**
```
ATPValidationError: Invalid DID format
```
**Diagnostic:**
```javascript
import { DIDUtils } from '@atp/sdk';
function validateDID(did) {
const parsed = DIDUtils.parseDID(did);
if (!parsed) {
console.error('Invalid DID format:', did);
console.log('Expected format: did:method:network:identifier');
return false;
}
console.log('DID components:', parsed);
return true;
}
// Test your DID
validateDID('did:atp:testnet:abc123');
```
**Common DID Issues:**
```javascript
// ❌ Wrong format
'atp:testnet:abc123' // Missing 'did:' prefix
'did:atp:abc123' // Missing network
'did:atp:testnet:' // Missing identifier
'did:atp:testnet:ABC-123' // Invalid characters
// ✓ Correct format
'did:atp:testnet:abc123' // Valid
'did:atp:mainnet:def456' // Valid
'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK' // Valid
```
### Private Key Issues
**Issue: Signature verification fails**
```
ATPAuthenticationError: Invalid signature
```
**Diagnostic:**
```javascript
import { CryptoUtils } from '@atp/sdk';
async function testKeyPair(publicKey, privateKey) {
try {
// Test data
const testData = 'Hello, ATP!';
// Sign with private key
const signature = await CryptoUtils.signData(testData, privateKey);
console.log('Signature created:', signature.substring(0, 20) + '...');
// Verify with public key
const isValid = await CryptoUtils.verifySignature(testData, signature, publicKey);
console.log('Signature valid:', isValid);
if (!isValid) {
console.error('Key pair mismatch!');
}
} catch (error) {
console.error('Key test failed:', error.message);
if (error.message.includes('Invalid key')) {
console.log('Check key format (should be hex)');
}
}
}
// Test your keys
await testKeyPair(yourPublicKey, yourPrivateKey);
```
**Common Key Issues:**
```javascript
// ❌ Wrong format
const privateKey = 'BEGIN PRIVATE KEY...'; // PEM format
const privateKey = 'abc123'; // Too short
const privateKey = 'gggg...'; // Invalid hex
// ✓ Correct format (64 character hex string)
const privateKey = 'a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456';
// Check key length
if (privateKey.length !== 64) {
console.error('Private key should be 64 hex characters');
}
// Check hex format
if (!/^[0-9a-fA-F]+$/.test(privateKey)) {
console.error('Private key should contain only hex characters');
}
```
### Token Issues
**Issue: JWT token expired or invalid**
```
ATPAuthenticationError: Token expired
```
**Diagnostic:**
```javascript
import { JWTUtils } from '@atp/sdk';
function debugToken(token) {
try {
const decoded = JWTUtils.decodeJWT(token);
if (!decoded) {
console.error('Invalid token format');
return;
}
console.log('Token header:', decoded.header);
console.log('Token payload:', decoded.payload);
// Check expiration
const now = Math.floor(Date.now() / 1000);
const exp = decoded.payload.exp;
if (exp && exp < now) {
console.error('Token expired:', new Date(exp * 1000));
} else {
console.log('Token expires:', new Date(exp * 1000));
}
// Check required fields
const requiredFields = ['iss', 'sub', 'aud'];
requiredFields.forEach(field => {
if (!decoded.payload[field]) {
console.warn(`Missing required field: ${field}`);
}
});
} catch (error) {
console.error('Token debug failed:', error.message);
}
}
// Debug your token
debugToken(yourToken);
```
### MFA Issues
**Issue: MFA verification fails**
```
ATPAuthenticationError: MFA verification failed
```
**Diagnostic:**
```javascript
// Check MFA status
try {
const mfaStatus = await client.identity.getMFAStatus(did);
console.log('MFA enabled:', mfaStatus.data.enabled);
console.log('MFA methods:', mfaStatus.data.methods);
if (mfaStatus.data.enabled && mfaStatus.data.methods.length === 0) {
console.error('MFA enabled but no methods configured');
}
} catch (error) {
console.error('Cannot check MFA status:', error.message);
}
// Test TOTP generation (for debugging)
function generateTOTP(secret, window = 0) {
const time = Math.floor(Date.now() / 1000 / 30) + window;
// TOTP generation logic...
return totp;
}
// Try different time windows
for (let window = -2; window <= 2; window++) {
const code = generateTOTP(secret, window);
console.log(`Window ${window}: ${code}`);
}
```
## Performance Problems
### Slow Response Times
**Issue: API calls taking too long**
**Diagnostic:**
```javascript
// Measure operation timing
async function measurePerformance(operation, ...args) {
const startTime = performance.now();
try {
const result = await operation(...args);
const duration = performance.now() - startTime;
console.log(`Operation completed in ${duration.toFixed(2)}ms`);
if (duration > 5000) {
console.warn('Slow operation detected');
}
return result;
} catch (error) {
const duration = performance.now() - startTime;
console.error(`Operation failed after ${duration.toFixed(2)}ms:`, error.message);
throw error;
}
}
// Test different operations
await measurePerformance(client.identity.resolve, 'did:atp:testnet:test');
await measurePerformance(client.credentials.verify, credentialId);
```
**Solutions:**
```javascript
// 1. Implement caching
const cache = new Map();
async function cachedResolve(did) {
if (cache.has(did)) {
return cache.get(did);
}
const result = await client.identity.resolve(did);
cache.set(did, result);
// Set TTL
setTimeout(() => cache.delete(did), 300000); // 5 minutes
return result;
}
// 2. Use parallel operations
const [identity, credentials] = await Promise.all([
client.identity.resolve(did),
client.credentials.query({ holder: did })
]);
// 3. Optimize batch operations
async function batchResolve(dids) {
const batchSize = 10;
const results = [];
for (let i = 0; i < dids.length; i += batchSize) {
const batch = dids.slice(i, i + batchSize);
const batchPromises = batch.map(did =>
client.identity.resolve(did).catch(error => ({ error, did }))
);
const batchResults = await Promise.allSettled(batchPromises);
results.push(...batchResults);
}
return results;
}
```
### Memory Issues
**Issue: Memory usage growing over time**
**Diagnostic:**
```javascript
// Monitor memory usage
function monitorMemory() {
const usage = process.memoryUsage();
console.log({
rss: Math.round(usage.rss / 1024 / 1024) + 'MB',
heapTotal: Math.round(usage.heapTotal / 1024 / 1024) + 'MB',
heapUsed: Math.round(usage.heapUsed / 1024 / 1024) + 'MB',
external: Math.round(usage.external / 1024 / 1024) + 'MB'
});
}
// Check memory every 30 seconds
setInterval(monitorMemory, 30000);
// Force garbage collection (development only)
if (global.gc) {
global.gc();
console.log('Garbage collection triggered');
}
```
**Solutions:**
```javascript
// 1. Implement proper cleanup
class ATPService {
constructor() {
this.client = new ATPClient(config);
this.cache = new Map();
this.cleanupInterval = setInterval(() => this.cleanup(), 300000);
}
cleanup() {
// Clear expired cache entries
this.cache.clear();
// Force garbage collection if available
if (global.gc) {
global.gc();
}
}
destroy() {
clearInterval(this.cleanupInterval);
this.client.cleanup();
this.cache.clear();
}
}
// 2. Use weak references for caches
const cache = new WeakMap();
// 3. Limit cache size
class LimitedCache {
constructor(maxSize = 1000) {
this.maxSize = maxSize;
this.cache = new Map();
}
set(key, value) {
if (this.cache.size >= this.maxSize) {
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(key, value);
}
}
```
## Error Messages
### Common Error Codes and Solutions
| Error Code | Description | Solution |
|------------|-------------|----------|
| `ECONNREFUSED` | Connection refused | Check if services are running, verify ports |
| `ETIMEDOUT` | Request timeout | Increase timeout, check network connectivity |
| `ENOTFOUND` | DNS resolution failed | Check hostname, use IP address, verify DNS |
| `INVALID_DID` | Malformed DID | Verify DID format: `did:method:network:id` |
| `TOKEN_EXPIRED` | JWT token expired | Refresh token or create new one |
| `INVALID_SIGNATURE` | Crypto signature invalid | Check private key format and pairing |
| `MFA_REQUIRED` | Multi-factor auth needed | Complete MFA verification flow |
| `ACCESS_DENIED` | Insufficient permissions | Check user permissions and trust level |
| `QUOTA_EXCEEDED` | Rate limit hit | Implement backoff, check rate limits |
| `SCHEMA_INVALID` | Invalid data schema | Validate input against schema |
### Detailed Error Handling
```javascript
function handleATPError(error) {
console.error('ATP Error Details:');
console.error('- Type:', error.constructor.name);
console.error('- Code:', error.code);
console.error('- Message:', error.message);
console.error('- Request ID:', error.requestId);
console.error('- Timestamp:', error.timestamp);
if (error.details) {
console.error('- Details:', JSON.stringify(error.details, null, 2));
}
// Specific handling
switch (error.code) {
case 'ECONNREFUSED':
console.log('\n🔧 Troubleshooting steps:');
console.log('1. Check if ATP services are running');
console.log('2. Verify service ports (3000-3004)');
console.log('3. Check firewall settings');
break;
case 'INVALID_DID':
console.log('\n🔧 DID Format Help:');
console.log('Expected: did:method:network:identifier');
console.log('Example: did:atp:testnet:abc123');
break;
case 'TOKEN_EXPIRED':
console.log('\n🔧 Token Solutions:');
console.log('1. Refresh the token');
console.log('2. Generate a new token with longer expiry');
console.log('3. Implement automatic token refresh');
break;
}
}
// Usage in catch blocks
try {
await client.identity.resolve(did);
} catch (error) {
handleATPError(error);
}
```
## Debugging Tools
### Enable Debug Mode
```javascript
// Enable SDK debug mode
const config = {
baseUrl: 'http://localhost',
debug: true,
logging: {
level: 'debug',
requests: true,
responses: true
}
};
// Environment variable
process.env.ATP_DEBUG = 'true';
process.env.DEBUG = 'atp:*';
```
### Request/Response Logging
```javascript
// Custom request interceptor
import axios from 'axios';
axios.interceptors.request.use(request => {
console.log('🔄 ATP Request:', {
method: request.method?.toUpperCase(),
url: request.url,
headers: request.headers,
data: request.data
});
return request;
});
axios.interceptors.response.use(
response => {
console.log('✅ ATP Response:', {
status: response.status,
url: response.config.url,
data: response.data
});
return response;
},
error => {
console.error('❌ ATP Error:', {
status: error.response?.status,
url: error.config?.url,
message: error.message,
data: error.response?.data
});
return Promise.reject(error);
}
);
```
### Network Diagnostics
```javascript
// Comprehensive network test
async function runNetworkDiagnostics(config) {
console.log('🔍 Running ATP Network Diagnostics...\n');
const services = {
identity: config.services?.identity || `${config.baseUrl}:3001`,
credentials: config.services?.credentials || `${config.baseUrl}:3002`,
permissions: config.services?.permissions || `${config.baseUrl}:3003`,
audit: config.services?.audit || `${config.baseUrl}:3004`,
gateway: config.services?.gateway || `${config.baseUrl}:3000`
};
for (const [service, url] of Object.entries(services)) {
console.log(`Testing ${service} service...`);
try {
const startTime = Date.now();
const response = await fetch(`${url}/health`, {
signal: AbortSignal.timeout(10000)
});
const duration = Date.now() - startTime;
if (response.ok) {
console.log(`✅ ${service}: OK (${duration}ms)`);
} else {
console.log(`⚠️ ${service}: HTTP ${response.status} (${duration}ms)`);
}
} catch (error) {
console.log(`❌ ${service}: ${error.message}`);
}
}
console.log('\n📊 Diagnostic complete');
}
// Run diagnostics
await runNetworkDiagnostics(config);
```
### Performance Profiling
```javascript
// Performance profiler
class ATPProfiler {
constructor() {
this.operations = new Map();
}
start(operation) {
this.operations.set(operation, {
startTime: performance.now(),
startMemory: process.memoryUsage()
});
}
end(operation) {
const start = this.operations.get(operation);
if (!start) return;
const endTime = performance.now();
const endMemory = process.memoryUsage();
const stats = {
duration: endTime - start.startTime,
memoryDelta: endMemory.heapUsed - start.startMemory.heapUsed
};
console.log(`📈 ${operation}:`, {
duration: `${stats.duration.toFixed(2)}ms`,
memory: `${Math.round(stats.memoryDelta / 1024)}KB`
});
this.operations.delete(operation);
return stats;
}
}
// Usage
const profiler = new ATPProfiler();
profiler.start('identity.resolve');
const result = await client.identity.resolve(did);
profiler.end('identity.resolve');
```
## Getting Help
### Community Resources
- **Documentation**: [https://docs.atp.protocol](https://docs.atp.protocol)
- **GitHub Issues**: [https://github.com/atp/sdk/issues](https://github.com/atp/sdk/issues)
- **Discord Community**: [https://discord.gg/atp](https://discord.gg/atp)
- **Stack Overflow**: Tag your questions with `atp-protocol`
### Reporting Issues
When reporting issues, include:
```javascript
// System information
console.log('System Info:', {
nodeVersion: process.version,
platform: process.platform,
arch: process.arch,
atpSdkVersion: require('@atp/sdk/package.json').version
});
// Configuration (sanitized)
console.log('Config:', {
baseUrl: config.baseUrl,
timeout: config.timeout,
retries: config.retries,
// Don't include sensitive data like private keys
});
// Error details
console.log('Error:', {
type: error.constructor.name,
code: error.code,
message: error.message,
stack: error.stack.split('\n').slice(0, 10).join('\n')
});
```
### Professional Support
For enterprise support:
- **Email**: enterprise@atp.protocol
- **Support Portal**: [https://support.atp.protocol](https://support.atp.protocol)
- **SLA**: 24/7 support available for enterprise customers
### Emergency Contacts
For critical production issues:
- **Emergency Hotline**: +1-800-ATP-HELP
- **Incident Slack**: #atp-incidents
- **On-call Engineer**: Available 24/7 for Tier 1 customers
Remember to check the [FAQ](./faq.md) and [Known Issues](./known-issues.md) sections before reporting new issues.