diff --git a/README.md b/README.md index 4b8ed2e..97b844d 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,19 @@ END:VCALENDAR `, function(err, data) { console.log(data); }); ``` +Note: When using the `ical.async.*` functions in a separate async context from your main code, +errors will be thrown in that separate context. Therefore, you must wrap these function calls +in try/catch blocks to properly handle any errors. For example: + +```javascript +try { + const events = await ical.async.parseFile('calendar.ics'); + // Process events +} catch (error) { + console.error('Failed to parse calendar:', error); +} +``` + ### autodetect These are the old API examples, which still work and will be converted to the new API automatically. Functions with callbacks provided will also have better performance over the older versions even if they use the old API. diff --git a/ical.js b/ical.js index 33b26d6..2d088ca 100644 --- a/ical.js +++ b/ical.js @@ -372,7 +372,7 @@ const exdateParameter = function (name) { if (typeof exdate[name].toISOString === 'function') { curr[name][exdate[name].toISOString().slice(0, 10)] = exdate[name]; } else { - throw new TypeError('No toISOString function in exdate[name]', exdate[name]); + throw new TypeError('No toISOString function in exdate[name] = ' + exdate[name]); } } } @@ -548,7 +548,7 @@ module.exports = { if (typeof curr.recurrenceid.toISOString === 'function') { par[curr.uid].recurrences[curr.recurrenceid.toISOString().slice(0, 10)] = recurrenceObject; } else { // Removed issue 56 - throw new TypeError('No toISOString function in curr.recurrenceid', curr.recurrenceid); + throw new TypeError('No toISOString function in curr.recurrenceid =' + curr.recurrenceid); } } @@ -623,10 +623,10 @@ module.exports = { rule = rule.replace(/\.\d{3}/, ''); } catch (error) { // This should not happen, issue #56 - throw new Error('ERROR when trying to convert to ISOString', error); + throw new Error('ERROR when trying to convert to ISOString ' + error); } } else { - throw new Error('No toISOString function in curr.start', curr.start); + throw new Error('No toISOString function in curr.start ' + curr.start); } } @@ -645,11 +645,23 @@ module.exports = { URL: storeParameter('url'), UID: storeParameter('uid'), LOCATION: storeParameter('location'), - DTSTART(value, parameters, curr, stack) { - curr = dateParameter('start')(value, parameters, curr, stack); - return typeParameter('datetype')(value, parameters, curr); + DTSTART(value, parameters, curr, stack, line) { + // If already defined, this is a duplicate for this event + if (curr.start === undefined) { + curr = dateParameter('start')(value, parameters, curr, stack); + return typeParameter('datetype')(value, parameters, curr); + } + + throw new Error('duplicate DTSTART encountered, line=' + line); + }, + DTEND(value, parameters, curr, stack, line) { + // If already defined, this is a duplicate for this event + if (curr.end === undefined) { + return dateParameter('end')(value, parameters, curr, stack); + } + + throw new Error('duplicate DTEND encountered, line=' + line); }, - DTEND: dateParameter('end'), EXDATE: exdateParameter('exdate'), ' CLASS': storeParameter('class'), // Should there be a space in this property? TRANSP: storeParameter('transparency'),