Skip to main content

Troubleshooting

Installation Issues

"Module not found" error after SDK installation

Terminal — clear cache and reinstall
# Clear npm cache and reinstall
npm cache clean --force
rm -rf node_modules package-lock.json
npm install
npm install ./votr-vote-sdk-1.0.0.tgz --legacy-peer-deps

Peer dependency warnings

The --legacy-peer-deps flag is required for this package. This is normal and expected.

TypeScript errors

The SDK includes its own TypeScript definitions. If you're still getting errors, try:

Terminal — add React Native type defs
npm install @types/react @types/react-native --save-dev

Authentication Issues

"Invalid client credentials" error

  • OAuth API returns 401 or 403 error.
  • Authentication fails.
  • Verify Client ID and Client Secret are correct.
  • Ensure no extra spaces or characters.
  • Confirm credentials are stored securely on your backend.
  • Verify you're using the correct environment URL.
  • Contact the VOTR team to verify credentials.

Token expiration errors

  • API calls work initially but fail after an hour.
  • Token expired error messages.

OAuth tokens expire after 1 hour. Implement token caching and refresh:

auth.ts — cache + refresh
const getValidToken = async () => {
const now = Date.now();

if (cachedToken && cachedToken.expires > now) {
return cachedToken.access_token;
}

const newToken = await getOAuthToken();
cachedToken = {
access_token: newToken.access_token,
expires: now + newToken.expires_in * 1000,
};

return cachedToken.access_token;
};

API Issues

"Shareholder not found" error

  • User exists but the API returns "shareholder not found".
  • Voting URL generation fails.
  • Verify the email address is registered for the event.
  • Check the eventId is correct and formatted properly.
  • Ensure the voting period is active.
  • Contact the event administrator to verify user registration.

Network request failing

  • API calls timeout or fail.
  • Connection errors.
  • Check internet connectivity.
  • Verify API endpoints — Development https://api-dev.govotr.com, Production https://api.govotr.com.
  • Ensure proper headers are included.
  • Implement retry logic for network failures (see code below).
fetchWithRetry.ts — exponential backoff
const fetchWithRetry = async (url: string, options: any, retries = 3) => {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
return response;
} catch (error) {
if (i === retries - 1) throw error;
await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
}
}
};

SDK Component Issues

WebView not opening or blank screen

  • Button press doesn't open voting interface.
  • Blank white screen appears.
  • Modal opens but no content.
  • Check that the voting URL is valid and not empty.
  • Verify the URL format is correct (should contain ID).
  • Test with a known working URL.
  • Check the console for JavaScript errors.
  • Ensure WebView has proper permissions in your app.
VoteButton.tsx — log the URL
console.log("Voting URL:", votingUrl);
console.log("URL is valid:", votingUrl && votingUrl.length > 0);

Button not responding to press

  • Button appears but doesn't respond to taps.
  • No console logs from onPress handler.
  • Check whether the button is disabled: isDisabled={false}.
  • Verify onPress is defined.
  • Check for overlapping views that may intercept touches.
  • Ensure button has proper dimensions.
VoteButton.tsx — minimum tap target
<VoteNowButton
URL={votingUrl}
isDisabled={false}
onPress={() => console.log("Button pressed")}
buttonStyle={{
minHeight: 44,
minWidth: 200,
}}
/>

Modal / WebView crashes or freezes

  • App crashes when voting modal opens.
  • WebView becomes unresponsive.
  • Memory issues during voting.
  • Implement proper cleanup on component unmount.
  • Add error boundaries around the SDK component.
  • Monitor memory usage during development.
VoteButton.tsx — unmount cleanup
useEffect(() => {
return () => {
setVotingUrl("");
};
}, []);

Error Handling Patterns

SDK error types

VoteButton.tsx — map SDK errors to user messages
<VoteNowButton
URL={votingUrl}
onError={(error) => {
console.error("SDK Error:", error);

let userMessage = "An unexpected error occurred during voting.";

if (error.includes("network")) {
userMessage = "Network connection lost. Please check your internet connection.";
} else if (error.includes("timeout")) {
userMessage = "Voting session timed out. Please try again.";
} else if (error.includes("permission")) {
userMessage = "You do not have permission to access this voting session.";
} else if (error.includes("invalid_token")) {
userMessage = "Your voting session has expired. Please try again.";
} else if (error.includes("already_voted")) {
userMessage = "You have already submitted your vote for this event.";
}

Alert.alert("Voting Error", userMessage);
setVotingUrl("");
}}
/>

API error handling

handleApiError.ts — status-aware error helper
const handleApiError = (error: any, context: string) => {
console.error(`${context} error:`, error);

if (error.response) {
const status = error.response.status;
const message = error.response.data?.message || "Unknown error";

switch (status) {
case 401:
return "Authentication failed. Please check your credentials.";
case 403:
return "You don't have permission to perform this action.";
case 404:
return "The requested resource was not found.";
case 500:
return "Server error. Please try again later.";
default:
return `Error ${status}: ${message}`;
}
} else if (error.request) {
return "Network error. Please check your internet connection.";
} else {
return `Unexpected error: ${error.message}`;
}
};

Performance Tips

Token caching

tokenCache.ts — reuse OAuth tokens until expiry
const tokenCache = { token: null, expires: 0 };

const getCachedToken = async () => {
if (tokenCache.token && Date.now() < tokenCache.expires) {
return tokenCache.token;
}

const response = await getOAuthToken();
tokenCache.token = response.access_token;
tokenCache.expires = Date.now() + response.expires_in * 1000;

return tokenCache.token;
};

Preload voting URLs

VoteScreen.tsx — fetch the URL early
useEffect(() => {
if (userEmail && eventId && !votingUrl) {
generateVotingUrl(userEmail, eventId);
}
}, [userEmail, eventId]);

Loading states

VoteScreen.tsx — disable button while loading
const [isLoading, setIsLoading] = useState(false);

<VoteNowButton
URL={votingUrl}
isDisabled={isLoading || !votingUrl}
label={isLoading ? "Loading..." : "Vote Now"}
/>;

Memory management

VoteScreen.tsx — release on unmount
useEffect(() => {
return () => {
setVotingUrl("");
tokenCache.token = null;
};
}, []);

Getting Additional Help

Development Resources

Contact Support

When contacting support, please include:

  1. Error messages (exact text).

  2. Console logs (if available).

  3. SDK version (1.0.0).

  4. Platform (React Native / React).

  5. Environment (Development / Production).

  6. Steps to reproduce the issue.

Debug Checklist

Before reporting issues, verify:

Pre-flight checks
0 / 9

If you're still experiencing issues, contact the VOTR team with your specific error details and logs.