Troubleshooting
This document provides solutions to common Lovrabet SDK issues to help you quickly diagnose and fix problems.
đ§ Common Issue Diagnosisâ
Problem Diagnosis Processâ
When encountering issues, please troubleshoot in the following order:
- Check Error Messages - View console error logs
- Verify Configuration - Confirm SDK configuration is correct
- Check Network - View network request status
- Verify Permissions - Confirm API access permissions
- Check Documentation - Review this document to check usage
Enable Detailed Loggingâ
// Enable detailed error logging
const client = createClient({
options: {
onError: (error) => {
console.group("đ Lovrabet SDK Error Details");
console.log("đ Message:", error.message);
console.log("đĸ Status:", error.status);
console.log("đ URL:", error.url);
console.log("đ¤ Request Data:", error.requestData);
console.log("đĨ Response Data:", error.responseData);
console.log("âąī¸ Timestamp:", new Date().toISOString());
console.log("đ Stack:", error.stack);
console.groupEnd();
},
},
});
â Configuration-Related Issuesâ
Q1: "Cannot find module '@lovrabet/sdk'"â
Problem Description: Project cannot find SDK module
Solution:
# Confirm SDK is installed
npm list @lovrabet/sdk
# If not installed, please install
npm install @lovrabet/sdk
# If TypeScript project, confirm type support
npm install --save-dev typescript
Q2: "registerModels is not a function"â
Problem Description: Import function issue
Solution:
// â Wrong import method
import lovrabetSdk from "@lovrabet/sdk";
lovrabetSdk.registerModels(config); // Will error
// â
Correct import method
import { registerModels, createClient } from "@lovrabet/sdk";
registerModels(config);
Q3: "No configuration found for apiConfigName 'default'"â
Problem Description: Default configuration not found
Solution:
// â Problem: Using without registering configuration
const client = createClient(); // Will error
// â
Solution: Register configuration first
registerModels({
appCode: "your-app-code",
models: {
users: { tableName: "users", datasetCode: "your-dataset-id" },
},
});
const client = createClient(); // Works normally
Q4: AppCode Configuration Issueâ
Problem Description: appCode configuration error or missing
Solution:
// Check environment variables
console.log("AppCode:", process.env.REACT_APP_LOVRABET_APP_CODE);
// Ensure configuration is correct
const config = {
appCode: "your-actual-app-code", // Don't use "your-app-code"
models: {
// ...
},
};
// Validate configuration
if (!config.appCode) {
throw new Error("AppCode is required");
}
đ Authentication-Related Issuesâ
Q5: "Authentication failed" / 401 Errorâ
Problem Description: Authentication failed, cannot access API
Solution:
// 1. Check if token is set
const client = createClient();
console.log("Current token:", client.getConfig().token);
// 2. Set token
client.setToken("your-valid-token");
// 3. Check token format
if (token && !token.startsWith("Bearer ")) {
client.setToken(`Bearer ${token}`);
}
// 4. Check if token is expired
const isTokenExpired = (token: string) => {
try {
const payload = JSON.parse(atob(token.split(".")[1]));
return payload.exp * 1000 < Date.now();
} catch {
return true;
}
};
Q6: OpenAPI Key Authentication Issueâ
Problem Description: Authentication failed when using OpenAPI keys
Solution:
// Check key configuration
const client = createClient({
accessKey: process.env.LOVRABET_ACCESS_KEY,
secretKey: process.env.LOVRABET_SECRET_KEY,
});
// Verify keys exist
const config = client.getConfig();
console.log("Has Access Key:", !!config.accessKey);
console.log("Has Secret Key:", !!config.secretKey);
// Ensure environment variables are set correctly
if (!process.env.LOVRABET_ACCESS_KEY) {
console.error("Missing LOVRABET_ACCESS_KEY environment variable");
}
Q7: Cookie Authentication Issueâ
Problem Description: Cookie authentication failed in browser
Solution:
// Check Cookie settings
document.cookie.split(";").forEach((cookie) => {
console.log("Cookie:", cookie.trim());
});
// Ensure domain and path are set correctly
// Check if on same-origin domain
console.log("Current origin:", window.location.origin);
console.log("API endpoint:", client.getConfig().serverUrl);
đ Network-Related Issuesâ
Q8: "Network Error" / Connection Failedâ
Problem Description: Network request failed
Solution:
// 1. Check server address
const client = createClient({
serverUrl: "https://api.lovrabet.com", // Ensure address is correct
});
// 2. Check network connection
const testConnection = async () => {
try {
const response = await fetch("https://api.lovrabet.com/health");
console.log("API health check:", response.status);
} catch (error) {
console.error("Network connection issue:", error);
}
};
// 3. Check CORS settings (frontend)
// Ensure server has correct CORS headers configured
Q9: Request Timeout Issueâ
Problem Description: Requests frequently timeout
Solution:
// Increase timeout time
const client = createClient({
options: {
timeout: 60000, // 60 seconds
},
});
// Implement request retry
const withRetry = async <T>(
operation: () => Promise<T>,
maxRetries = 3
): Promise<T> => {
let lastError: any;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error: any) {
lastError = error;
if (error.code === "TIMEOUT" && attempt < maxRetries) {
console.log(`Request timeout, retrying ${attempt}/${maxRetries}`);
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
continue;
}
throw error;
}
}
throw lastError;
};
Q10: Rate Limit Issueâ
Problem Description: Receiving 429 Too Many Requests error
Solution:
// Implement request rate limiting
class RateLimiter {
private requests: number[] = [];
private maxRequests: number;
private timeWindow: number;
constructor(maxRequests = 100, timeWindowMs = 60000) {
this.maxRequests = maxRequests;
this.timeWindow = timeWindowMs;
}
async waitForAvailability(): Promise<void> {
const now = Date.now();
// Clean expired request records
this.requests = this.requests.filter(
(time) => now - time < this.timeWindow
);
if (this.requests.length >= this.maxRequests) {
const oldestRequest = Math.min(...this.requests);
const waitTime = this.timeWindow - (now - oldestRequest);
console.log(`Rate limit reached, waiting ${waitTime}ms`);
await new Promise((resolve) => setTimeout(resolve, waitTime));
return this.waitForAvailability();
}
this.requests.push(now);
}
}
const rateLimiter = new RateLimiter();
const makeRequest = async (operation: () => Promise<any>) => {
await rateLimiter.waitForAvailability();
return operation();
};
đ Data-Related Issuesâ
Q11: "Dataset not found" Errorâ
Problem Description: Dataset does not exist or no access permission
Solution:
// Verify dataset ID
const verifyDataset = async (datasetCode: string) => {
try {
// Try to get dataset information
const response = await client.models.yourModel.filter({ pageSize: 1 });
console.log("Dataset verification successful:", response.total);
} catch (error: any) {
if (error.status === 404) {
console.error("Dataset does not exist:", datasetCode);
} else if (error.status === 403) {
console.error("No access permission:", datasetCode);
}
throw error;
}
};
// Check dataset ID in configuration
console.log("Configured dataset ID:", client.getConfig().models);
Q12: Data Format Issueâ
Problem Description: Returned data format doesn't match expectations
Solution:
// Add data validation
const validateResponseData = (data: any, expectedFields: string[]) => {
if (!data || typeof data !== "object") {
throw new Error("Invalid response data format");
}
const missingFields = expectedFields.filter((field) => !(field in data));
if (missingFields.length > 0) {
console.warn("Missing fields:", missingFields);
}
return data;
};
// Validate data when using
const users = await client.models.users.filter();
users.tableData.forEach((user) => {
validateResponseData(user, ["id", "name", "email"]);
});
Q13: Pagination Data Issueâ
Problem Description: Pagination parameters incorrect or pagination data abnormal
Solution:
// Validate pagination parameters
const validatePaginationParams = (params: any) => {
const { currentPage, pageSize } = params;
if (currentPage && (currentPage < 1 || !Number.isInteger(currentPage))) {
throw new Error("currentPage must be a positive integer");
}
if (
pageSize &&
(pageSize < 1 || pageSize > 1000 || !Number.isInteger(pageSize))
) {
throw new Error("pageSize must be between 1 and 1000");
}
return params;
};
// Safe pagination query
const safeGetList = async (modelName: string, params: any = {}) => {
const validatedParams = validatePaginationParams(params);
return await client.models[modelName].filter(validatedParams);
};
đ Debugging Tools and Tipsâ
Debug Helper Classâ
class LovrabetDebugger {
private client: any;
constructor(client: any) {
this.client = client;
}
// Test connection
async testConnection(): Promise<boolean> {
try {
// Try to get small amount of data to test connection
await this.client.models[Object.keys(this.client.getConfig().models)[0]].filter({ pageSize: 1 });
console.log("â
Connection test successful");
return true;
} catch (error: any) {
console.error("â Connection test failed:", error.message);
return false;
}
}
// Check configuration
checkConfiguration(): void {
const config = this.client.getConfig();
console.group("đ§ Configuration Check");
console.log("AppCode:", config.appCode);
console.log("Environment:", config.env);
console.log("Server URL:", config.serverUrl);
console.log("Has Token:", !!config.token);
console.log("Has Access Key:", !!config.accessKey);
console.log("Models:", Object.keys(config.models || {}));
console.groupEnd();
}
// Test all models
async testAllModels(): Promise<void> {
const config = this.client.getConfig();
const modelNames = Object.keys(config.models || {});
console.log("đ§Ē Testing all models...");
for (const modelName of modelNames) {
try {
const response = await this.client.models[modelName].filter({ pageSize: 1 });
console.log(`â
${modelName}: ${response.total} records`);
} catch (error: any) {
console.error(`â ${modelName}: ${error.message}`);
}
}
}
// Performance test
async performanceTest(modelName: string, iterations = 10): Promise<void> {
console.log(`⥠Performance test ${modelName} (${iterations} requests)`);
const times: number[] = [];
for (let i = 0; i < iterations; i++) {
const start = Date.now();
try {
await this.client.models[modelName].filter({ pageSize: 10 });
const duration = Date.now() - start;
times.push(duration);
console.log(`Request ${i + 1}: ${duration}ms`);
} catch (error: any) {
console.error(`Request ${i + 1} failed:`, error.message);
}
}
if (times.length > 0) {
const avg = times.reduce((a, b) => a + b, 0) / times.length;
const min = Math.min(...times);
const max = Math.max(...times);
console.log(`đ Performance Statistics:`);
console.log(`Average time: ${avg.toFixed(2)}ms`);
console.log(`Min time: ${min}ms`);
console.log(`Max time: ${max}ms`);
}
}
// Check permissions
async checkPermissions(modelName: string): Promise<void> {
console.log(`đ Checking ${modelName} permissions`);
const tests = [
{ name: "Read", action: () => this.client.models[modelName].filter({ pageSize: 1 }) },
{ name: "Create", action: () => this.client.models[modelName].create({ test: true }) },
{ name: "Update", action: () => this.client.models[modelName].update("test-id", { test: true }) },
{ name: "Delete", action: () => this.client.models[modelName].delete("test-id") },
];
for (const test of tests) {
try {
await test.action();
console.log(`â
${test.name}: Has permission`);
} catch (error: any) {
if (error.status === 403) {
console.log(`â ${test.name}: No permission`);
} else if (error.status === 404) {
console.log(`â ī¸ ${test.name}: Resource does not exist (may have permission)`);
} else {
console.log(`â ${test.name}: ${error.message}`);
}
}
}
}
}
// Use debugger
const debugger = new LovrabetDebugger(client);
// Run complete diagnostics
const runDiagnostics = async () => {
debugger.checkConfiguration();
await debugger.testConnection();
await debugger.testAllModels();
await debugger.checkPermissions("users");
await debugger.performanceTest("users", 5);
};
Browser Developer Toolsâ
// Add debugging methods in browser console
(window as any).lovrabetDebug = {
client,
// Quick test
async test() {
const debugger = new LovrabetDebugger(client);
await debugger.testConnection();
},
// View configuration
config() {
console.table(client.getConfig());
},
// View recent requests
requests: [],
// Add request listener
enableRequestLogging() {
const originalFetch = window.fetch;
(window as any).lovrabetDebug.requests = [];
window.fetch = function(...args) {
const start = Date.now();
const url = typeof args[0] === 'string' ? args[0] : args[0].url;
return originalFetch.apply(this, args).then(response => {
(window as any).lovrabetDebug.requests.push({
url,
status: response.status,
duration: Date.now() - start,
timestamp: new Date().toISOString(),
});
return response;
});
};
console.log("â
Request logging enabled, use lovrabetDebug.requests to view");
},
};
console.log("đ§ Debug tools loaded, use lovrabetDebug to access");
đ Getting Helpâ
Self-Troubleshooting Checklistâ
Before contacting technical support, please complete the following checks:
- Confirm SDK version is latest
- Check console for error messages
- Verify appCode and datasetCode configuration is correct
- Test network connection is normal
- Confirm API authentication configuration is correct
- Try simple test request
Provide Problem Informationâ
When technical support is needed, please provide the following information:
// Tool function to collect problem information
const collectProblemInfo = () => {
const info = {
sdkVersion: "1.0.0", // Check package.json
browser: navigator.userAgent,
timestamp: new Date().toISOString(),
config: {
appCode: client.getConfig().appCode,
env: client.getConfig().env,
hasToken: !!client.getConfig().token,
hasAccessKey: !!client.getConfig().accessKey,
modelsCount: Object.keys(client.getConfig().models || {}).length,
},
error: "Specific error message",
steps: "Reproduction steps",
};
console.log("Problem information:", JSON.stringify(info, null, 2));
return info;
};
Contact Channelsâ
- đ§ Technical Support Email - Send problem details and system information
- đŦ Internal Tech Group - Get quick community help
- đ Documentation Feedback - If you find documentation issues, please provide feedback
Common Check Commandsâ
# Check SDK version
npm list @lovrabet/sdk
# Check dependency conflicts
npm ls --depth=0
# Clear cache
npm cache clean --force
rm -rf node_modules package-lock.json
npm install
# Check environment variables
echo $REACT_APP_LOVRABET_APP_CODE
đ Best Practices to Prevent Issuesâ
- Use TypeScript - Find type errors at compile time
- Error Boundaries - Use error boundary components in React
- Input Validation - Validate user input and API responses
- Environment Management - Distinguish development and production environment configurations
- Monitor Logs - Log key operations and error information
- Test-Driven - Write unit tests and integration tests
- Progressive Deployment - Release and test features in stages
Hope these troubleshooting steps help you quickly resolve issues! If you still have questions, please contact the technical support team.