Skip to main content

Troubleshooting

This document provides solutions to common Lovrabet SDK problems, helping you quickly diagnose and fix issues.

🔧 Common Problem Diagnosis​

Diagnosis Process​

When encountering problems, follow these steps to troubleshoot:

  1. Check error messages - View console error logs
  2. Verify configuration - Confirm SDK configuration is correct
  3. Check network - View network request status
  4. Verify permissions - Confirm API access permissions
  5. Review documentation - Check usage against this documentation

Enable Verbose Logging​

// Enable verbose 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();
},
},
});

Q1: "Cannot find module '@lovrabet/sdk'"​

Problem Description: The project cannot find the SDK module

Solution:

# Confirm SDK is installed
npm list @lovrabet/sdk

# If not installed, install it
npm install @lovrabet/sdk

# If it's a TypeScript project, confirm type support
npm install --save-dev typescript

Q2: "registerModels is not a function"​

Problem Description: Import function issue

Solution:

// Incorrect 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: Cannot find default configuration

Solution:

// Problem: using without registering configuration first
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 is wrong or missing

Solution:

// Check environment variables
console.log("AppCode:", process.env.REACT_APP_LOVRABET_APP_CODE);

// Ensure correct configuration
const config = {
appCode: "your-actual-app-code", // Do not use "your-app-code"
models: {
// ...
},
};

// Validate configuration
if (!config.appCode) {
throw new Error("AppCode is required");
}

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 fails 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");
}

Problem Description: Cookie authentication fails in the 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 the same origin
console.log("Current origin:", window.location.origin);
console.log("API endpoint:", client.getConfig().serverUrl);

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 the server has correct CORS headers configured

Q9: Request Timeout Issue​

Problem Description: Requests frequently timeout

Solution:

// Increase timeout duration
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 timed out, retrying ${attempt}/${maxRetries}`);
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
continue;
}

throw error;
}
}

throw lastError;
};

Q10: Rate Limiting 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 up 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();
};

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 info
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 IDs:", client.getConfig().models);

Q12: Data Format Issue​

Problem Description: Returned data format does not 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 are incorrect or paginated data is 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 paginated 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 fetch a 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 not found (may have permission)`);
} else {
console.log(`${test.name}: ${error.message}`);
}
}
}
}
}

// Using the debugger
const debuggerInstance = new LovrabetDebugger(client);

// Run full diagnostics
const runDiagnostics = async () => {
debuggerInstance.checkConfiguration();
await debuggerInstance.testConnection();
await debuggerInstance.testAllModels();
await debuggerInstance.checkPermissions("users");
await debuggerInstance.performanceTest("users", 5);
};

Browser Developer Tools​

// Add debug methods in browser console
(window as any).lovrabetDebug = {
client,

// Quick test
async test() {
const debuggerInstance = new LovrabetDebugger(client);
await debuggerInstance.testConnection();
},

// View configuration
config() {
console.table(client.getConfig());
},

// View recent requests
requests: [],

// Add request logging
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-Service Troubleshooting Checklist​

Before contacting technical support, complete the following checks:

  • Confirm SDK version is up to date
  • Check console for error messages
  • Verify appCode and datasetCode configuration is correct
  • Test network connectivity
  • Confirm API authentication configuration is correct
  • Try a simple test request

Provide Problem Information​

When you need technical support, please provide the following information:

// Utility 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 - Report documentation issues

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 for Preventing Issues​

  1. Use TypeScript - Catch type errors at compile time
  2. Error Boundaries - Use error boundary components in React
  3. Input Validation - Validate user input and API responses
  4. Environment Management - Separate development and production environment configurations
  5. Monitoring Logs - Record key operations and error information
  6. Test-Driven - Write unit tests and integration tests
  7. Progressive Deployment - Release and test features in stages

We hope these troubleshooting steps help you resolve issues quickly! If you still have questions, please contact the technical support team.