Skip to content

NoriKV TypeScript Client Troubleshooting Guide

Solutions to common issues when using the TypeScript/JavaScript client SDK.

Connection Issues

"Connection refused" or ECONNREFUSED

Symptoms:

await client.connect();
// Error: connect ECONNREFUSED 127.0.0.1:9001

Solutions:

  1. Verify server is running:

    netstat -an | grep 9001
    lsof -i :9001
    

  2. Check client configuration:

    const client = new NoriKVClient({
      nodes: ['localhost:9001'], // Verify this address
      totalShards: 1024,
    });
    

  3. Test connectivity:

    telnet localhost 9001
    nc -zv localhost 9001
    

"Deadline exceeded" or timeout errors

Symptoms:

const result = await client.get(key);
// Error: Deadline exceeded

Solutions:

  1. Increase timeout:

    const client = new NoriKVClient({
      nodes: ['localhost:9001'],
      timeout: 10000, // 10 seconds
    });
    

  2. Enable retries:

    const client = new NoriKVClient({
      nodes: ['localhost:9001'],
      retry: {
        maxAttempts: 10,
        initialDelayMs: 100,
        maxDelayMs: 5000,
      },
    });
    

Performance Problems

Slow operations

Diagnosis:

console.time('put');
await client.put(key, value);
console.timeEnd('put'); // > 100ms consistently

Solutions:

  1. Use appropriate consistency level:

    const result = await client.get(key, {
      consistency: ConsistencyLevel.STALE_OK, // Fastest
    });
    

  2. Batch operations:

    await Promise.all(
      keys.map(k => client.put(k, value))
    );
    

  3. Check value sizes:

    console.log('Value size:', value.length, 'bytes');
    // Optimal: 100 bytes - 10 KB
    

High memory usage

Solutions:

  1. Close client when done:

    await client.close(); // Important!
    

  2. Clean up topology listeners:

    const unsubscribe = client.onTopologyChange(handler);
    unsubscribe(); // Clean up when done
    

  3. Use Node.js profiling:

    node --inspect index.js
    # Open chrome://inspect
    

Version Conflicts

Frequent VersionMismatchError

Symptoms:

await client.put(key, newValue, {
  ifMatchVersion: version,
});
// Error: Version mismatch

Solution - Implement retry loop:

async function casWithRetry(
  key: string,
  transform: (value: string) => string,
  maxRetries: number = 10
): Promise<void> {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const result = await client.get(key);
      const newValue = transform(bytesToString(result.value));

      await client.put(key, newValue, {
        ifMatchVersion: result.version,
      });
      return; // Success
    } catch (err) {
      if (!(err instanceof VersionMismatchError)) {
        throw err;
      }
      if (i === maxRetries - 1) {
        throw new Error('CAS failed after retries');
      }
      // Exponential backoff
      await new Promise(r => setTimeout(r, Math.pow(2, i) * 10));
    }
  }
}

Error Messages

"Key not found"

Handling:

try {
  const result = await client.get(key);
} catch (err) {
  if (err instanceof KeyNotFoundError) {
    // Use default value or create key
    return defaultValue;
  }
  throw err;
}

"Version mismatch"

Handling: See Version Conflicts above.

"Connection error"

Handling:

async function withRetry<T>(
  operation: () => Promise<T>
): Promise<T> {
  const maxAttempts = 3;
  for (let i = 0; i < maxAttempts; i++) {
    try {
      return await operation();
    } catch (err) {
      if (!(err instanceof ConnectionError) || i === maxAttempts - 1) {
        throw err;
      }
      await new Promise(r => setTimeout(r, Math.pow(2, i) * 100));
    }
  }
  throw new Error('Unreachable');
}

TypeScript-Specific Issues

Type errors with buffers

Problem:

const value = Buffer.from('hello');
await client.put(key, value); // Type error

Solution:

import { stringToBytes } from '@norikv/client';

const value = stringToBytes('hello'); // Uint8Array
await client.put(key, value);

Async/await not working

Problem:

client.put(key, value); // Promise not awaited
console.log('Done'); // Runs before put completes

Solution:

await client.put(key, value); // Await the promise
console.log('Done'); // Runs after put completes

Module resolution errors

Problem:

import { NoriKVClient } from '@norikv/client';
// Error: Cannot find module

Solution:

  1. Install package:

    npm install @norikv/client
    

  2. Check tsconfig.json:

    {
      "compilerOptions": {
        "moduleResolution": "node",
        "esModuleInterop": true
      }
    }
    

Browser Issues

"Buffer is not defined"

Solution - Add buffer polyfill:

npm install buffer

import { Buffer } from 'buffer';
globalThis.Buffer = Buffer;

gRPC not working in browser

Solution - Use gRPC-Web:

import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport';

// Configure client for browser
const transport = new GrpcWebFetchTransport({
  baseUrl: 'http://localhost:8080'
});

Common Pitfalls

1. Not awaiting promises

//  Bad
client.put(key, value); // Promise ignored

//  Good
await client.put(key, value);

2. Creating client per request

//  Bad
async function handleRequest() {
  const client = new NoriKVClient(config);
  await client.connect();
  await client.put(key, value);
  await client.close(); // Expensive!
}

//  Good
const client = new NoriKVClient(config);
await client.connect();
// Reuse client across requests

3. Not handling errors

//  Bad
const result = await client.get(key); // May throw

//  Good
try {
  const result = await client.get(key);
} catch (err) {
  if (err instanceof KeyNotFoundError) {
    return null;
  }
  throw err;
}

4. Mixing callbacks and async/await

//  Bad
client.put(key, value).then(() => {
  client.get(key).then(result => {
    console.log(result);
  });
});

//  Good
const version = await client.put(key, value);
const result = await client.get(key);
console.log(result);

Debugging Tips

Enable debug logging

// Set environment variable
process.env.DEBUG = 'norikv:*';

Use Node.js debugger

node --inspect-brk index.js
# Open chrome://inspect

Monitor operations

const start = Date.now();
await client.put(key, value);
console.log(`PUT took ${Date.now() - start}ms`);

Check client stats

const stats = client.getStats();
console.log('Stats:', JSON.stringify(stats, null, 2));

Getting Help