| name | evernote-common-errors |
| description | Diagnose and fix common Evernote API errors.
Use when encountering Evernote API exceptions, debugging failures,
or troubleshooting integration issues.
Trigger with phrases like "evernote error", "evernote exception",
"fix evernote issue", "debug evernote", "evernote troubleshooting".
|
| allowed-tools | Read, Write, Edit, Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Evernote Common Errors
Overview
Comprehensive guide to diagnosing and resolving Evernote API errors, including EDAMUserException, EDAMSystemException, and EDAMNotFoundException.
Prerequisites
- Basic Evernote SDK setup
- Understanding of Evernote data model
Error Types
Evernote uses three main exception types:
| Exception | When Thrown |
|---|
EDAMUserException | Client error - invalid input, permissions |
EDAMSystemException | Server error - rate limits, maintenance |
EDAMNotFoundException | Resource not found - invalid GUID |
EDAMUserException Errors
BAD_DATA_FORMAT
Cause: Invalid ENML content or malformed data
{
errorCode: 1,
parameter: 'Note.content'
}
'<en-note><p>Hello</p></en-note>'
`<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
<en-note><p>Hello</p></en-note>`
`<en-note><script>alert('hi')</script></en-note>`
`<en-note><p>Content only</p></en-note>`
'<en-note><p>Hello<br></en-note>'
'<en-note><p>Hello</p><br/></en-note>'
Fix: Validate ENML before sending:
function validateENML(content) {
const errors = [];
if (!content.includes('<?xml version="1.0"')) {
errors.push('Missing XML declaration');
}
if (!content.includes('<!DOCTYPE en-note')) {
errors.push('Missing DOCTYPE');
}
if (!content.includes('<en-note>')) {
errors.push('Missing <en-note> root element');
}
const forbidden = [
/<script/i, /<form/i, /<input/i, /<button/i,
/<iframe/i, /<object/i, /<embed/i, /<applet/i
];
forbidden.forEach(pattern => {
if (pattern.test(content)) {
errors.push(`Forbidden element: ${pattern.source}`);
}
});
if (/\s(class|id|onclick|onload|onerror)=/i.test(content)) {
errors.push('Forbidden attributes (class, id, event handlers)');
}
return { valid: errors.length === , errors };
}
DATA_REQUIRED
Cause: Missing required field
{
errorCode: 2,
parameter: 'Note.title'
}
const note = new Evernote.Types.Note();
note.title = 'Required Title';
note.content = validENMLContent;
PERMISSION_DENIED
Cause: API key lacks required permissions
{
errorCode: 3,
parameter: 'NoteStore.shareNote'
}
INVALID_AUTH
Cause: Invalid or expired authentication token
{
errorCode: 4,
parameter: 'authenticationToken'
}
async function checkTokenValidity(client) {
try {
const userStore = client.getUserStore();
await userStore.getUser();
return { valid: true };
} catch (error) {
if (error.errorCode === 4) {
return {
valid: false,
reason: 'Token expired or revoked',
action: 'Re-authenticate via OAuth'
};
}
throw error;
}
}
AUTH_EXPIRED
Cause: Token has passed expiration date
{
errorCode: 5,
parameter: 'authenticationToken'
}
function isTokenExpired(expirationTimestamp) {
return Date.now() > expirationTimestamp;
}
LIMIT_REACHED
Cause: Account limits exceeded
{
errorCode: 6,
parameter: 'Notebook.name'
}
async function canCreateNotebook(noteStore) {
const notebooks = await noteStore.listNotebooks();
return notebooks.length < 250;
}
QUOTA_REACHED
Cause: Monthly upload quota exceeded
{
errorCode: 7,
parameter: 'Note.content'
}
async function getRemainingQuota(userStore) {
const user = await userStore.getUser();
const accounting = user.accounting;
return {
uploadLimit: accounting.uploadLimit,
uploadLimitEnd: new Date(accounting.uploadLimitEnd),
uploaded: accounting.uploaded,
remaining: accounting.uploadLimit - accounting.uploaded
};
}
EDAMSystemException Errors
RATE_LIMIT_REACHED
Cause: Too many API calls per hour
{
errorCode: 19,
rateLimitDuration: 300
}
async function withRateLimitRetry(operation, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
if (error.errorCode === 19 && error.rateLimitDuration) {
console.log(`Rate limited. Waiting ${error.rateLimitDuration}s...`);
await sleep(error.rateLimitDuration * 1000);
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
SYSTEM_MAINTENANCE
Cause: Evernote service is under maintenance
{
errorCode: 1,
message: 'Service temporarily unavailable'
}
async function withMaintenanceRetry(operation) {
const delays = [1000, 5000, 15000, 60000];
for (const delay of delays) {
try {
return await operation();
} catch (error) {
if (error.message?.includes('temporarily unavailable')) {
console.log(`Service maintenance. Retrying in ${delay / 1000}s...`);
await sleep(delay);
continue;
}
throw error;
}
}
throw new Error('Service unavailable - maintenance ongoing');
}
EDAMNotFoundException Errors
Cause: Referenced resource doesn't exist
{
identifier: 'Note.guid',
key: '12345678-abcd-1234-efgh-invalid00000'
}
async function safeGetNote(noteStore, guid) {
try {
return await noteStore.getNote(guid, true, false, false, false);
} catch (error) {
if (error.identifier === 'Note.guid') {
console.log(`Note not found: ${guid}`);
return null;
}
throw error;
}
}
Error Handling Service
const Evernote = require('evernote');
class EvernoteErrorHandler {
static handle(error) {
if (error.errorCode !== undefined && error.parameter !== undefined) {
return this.handleUserException(error);
}
if (error.errorCode !== undefined && error.rateLimitDuration !== undefined) {
return this.handleSystemException(error);
}
if (error.identifier !== undefined) {
return this.handleNotFoundException(error);
}
return {
type: 'UNKNOWN',
message: error.message || 'Unknown Evernote error',
recoverable: false,
original: error
};
}
static handleUserException(error) {
codes = {
: { : , : },
: { : , : },
: { : , : },
: { : , : },
: { : , : },
: { : , : },
: { : , : }
};
info = codes[error.] || { : , : };
{
: ,
: error.,
: info.,
: error.,
: info.,
: [, ].(error.),
: error
};
}
() {
{
: ,
: error.,
: error.,
: ,
: ,
: error
};
}
() {
{
: ,
: error.,
: error.,
: ,
: ,
: error
};
}
}
. = ;
Usage Example
const ErrorHandler = require('./services/error-handler');
async function createNoteSafely(noteStore, note) {
try {
return await noteStore.createNote(note);
} catch (error) {
const handled = ErrorHandler.handle(error);
console.error('Evernote error:', handled.name || handled.type);
console.error('Parameter:', handled.parameter || handled.identifier);
console.error('Action:', handled.action);
if (handled.recoverable) {
console.log('Error is recoverable');
if (handled.rateLimitDuration) {
await sleep(handled.rateLimitDuration * 1000);
return noteStore.createNote(note);
}
}
throw error;
}
}
Output
- Understanding of all Evernote exception types
- Error code reference with solutions
- Reusable error handling service
- Rate limit retry implementation
Quick Reference
| Code | Exception | Cause | Fix |
|---|
| 1 | UserException | Bad data format | Validate ENML |
| 2 | UserException | Missing required field | Add required field |
| 3 | UserException | Permission denied | Check API key |
| 4 | UserException | Invalid auth | Re-authenticate |
| 5 | UserException | Auth expired | Refresh token |
| 6 | UserException | Limit reached | Check account limits |
| 7 | UserException | Quota reached | Check upload quota |
| 19 | SystemException | Rate limit | Wait rateLimitDuration |
| - | NotFoundException | GUID not found | Verify resource exists |
Resources
Next Steps
For debugging tools and techniques, see evernote-debug-bundle.