Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uncaught exception: No toISOString function in exdate[name] #172

Closed
ElAmarok opened this issue Dec 28, 2021 · 13 comments · Fixed by #348
Closed

uncaught exception: No toISOString function in exdate[name] #172

ElAmarok opened this issue Dec 28, 2021 · 13 comments · Fixed by #348

Comments

@ElAmarok
Copy link

No toISOString function in exdate[name]
TypeError: No toISOString function in exdate[name] at Object.EXDATE (/opt/iobroker/node_modules/node-ical/ical.js:299:17) at Object.handleObject (/opt/iobroker/node_modules/node-ical/ical.js:571:39) at Object.parseLines (/opt/iobroker/node_modules/node-ical/ical.js:623:18) at Immediate.<anonymous> (/opt/iobroker/node_modules/node-ical/ical.js:638:16) at processImmediate (internal/timers.js:464:21)

@xRealNeon
Copy link

Got the same error, any updates @jens-maus ?

@Apollon77
Copy link
Contributor

Apollon77 commented Jan 12, 2023

Can you try to get a minimal ics File that can reproduce this error?

Tis error happensd when exDate is somehow strange becaue it contains something BUT mot a valid date object, so finding the reason would be ideal

@sdetweil
Copy link
Contributor

@marsmaennchen @xRealNeon I had to put a fix in our application as the dates are returned from rrule.between() , not by ical.

                                        let dates=rrule.between(x,y) // get the list of rule matching dates
					dates = dates.filter((d) => {    // filter out any garbage dates.. usually when TZ is trash
						if (JSON.stringify(d) === "null") return false;
						else return true;
					});

@sdetweil
Copy link
Contributor

this should be closed as a dup of
#144

@johnhundley
Copy link

johnhundley commented Aug 5, 2024

I am getting this error after updating to a new version of node-ical. I have isolated the version in which the behavior changed, it changed between 0.12.6 and 0.12.7. The attached code will recreate the error (works in versions earlier than 0.12.7)

const ical = require('node-ical');

const myevents = "BEGIN:VEVENT\r\nDTSTART:20230105T191500Z\r\nDTEND:20230105T193000Z\r\nRRULE:FREQ=WEEKLY;INTERVAL=1\r\nDTSTART:20230105T193000Z\r\nDTEND:20230105T194500Z\r\nRRULE:FREQ=WEEKLY;INTERVAL=1\r\nEND:VEVENT\r\n";


async function doit(){
    var events = await ical.async.parseICS(myevents);
}
console.log("Starting....");
doit()
  .then(() => {
    console.log("Finished....");
    process.exit(0);
  })
  .catch(err => {
    console.error(err);
    process.exit(1);
  });

@sdetweil
Copy link
Contributor

sdetweil commented Oct 22, 2024

ok, this is a bad ics format.. has dual DTSTART/DTEND and RRULE.. so processes twice..per event

how to handle? the error is thrown because the curr.start is an array of dates... not a date object

for test
this works (for start...)

    DTSTART(value, parameters, curr, stack) {
      if(curr.start ==undefined){
        curr = dateParameter('start')(value, parameters, curr, stack);
        return typeParameter('datetype')(value, parameters, curr);
      }
      else {
        throw new Error('duplicate DTSTART encountered');
      }
    },

but this only catches start... end shows same duplicate problem (if no start)

curr.end= [
  2023-01-05T19:30:00.000Z { tz: 'Etc/UTC' },
  2023-01-05T19:45:00.000Z { tz: 'Etc/UTC' }
]

so, I propose this

    DTSTART(value, parameters, curr, stack) {
      if(curr.start == undefined){
        curr = dateParameter('start')(value, parameters, curr, stack);
        return typeParameter('datetype')(value, parameters, curr);
      }
      else {
        throw new Error('duplicate DTSTART encountered');
      }
    },
    DTEND(value, parameters, curr, stack){
      if(curr.end == undefined){
        curr = dateParameter('end')(value, parameters, curr, stack);
        return typeParameter('datetype')(value, parameters, curr);
      }
      else {
        throw new Error('duplicate DTEND encountered');
      }
    },

this doesn't work with DTEND hooked

@jens-maus what do you think? I sort of think this is an invalid testcase.. badly formatted ics,

@sdetweil
Copy link
Contributor

sdetweil commented Oct 22, 2024

this works for both . I added the line content in the throw, so one could find it in the ics data

    DTSTART(value, parameters, curr, stack, line) {
      if(curr.start ==undefined){
        curr = dateParameter('start')(value, parameters, curr, stack);
        return typeParameter('datetype')(value, parameters, curr);
      }
      else {
        throw new Error('duplicate DTSTART encountered, line='+line);
      }
    },
    DTEND(value, parameters, curr, stack, line){
      if(curr.end ==undefined){
        return dateParameter('end')(value, parameters, curr, stack);
      }
      else {
        throw new Error('duplicate DTEND encountered, line='+line);
      }
    },

for example w this testcase
Finished....events= "error processing duplicate DTSTART encountered, line=DTSTART:20230105T193000Z"
or
Finished....events= "error processing duplicate DTEND encountered, line=DTEND:20230105T194500Z"

@sdetweil
Copy link
Contributor

also, in this issue

async function doit(){
    var events = await ical.async.parseICS(myevents);
}

means that a try/catch in the mainline code wont work, as the doit() is in a separate context.

it DOES catch the throw if you wrap the calls to ical.async.parseICS(myevents); in try/catch then you would could return a diff result,

this demonstrates the try/catch and comm back to the mainline

const ical = require('node-ical');

const myevents = "BEGIN:VEVENT\r\nDTSTART:20230105T191500Z\r\nDTEND:20230105T193000Z\r\nRRULE:FREQ=WEEKLY;INTERVAL=1\r\nDTSTART:20230105T193000Z\r\nDTEND:20230105T194500Z\r\nRRULE:FREQ=WEEKLY;INTERVAL=1\r\nEND:VEVENT\r\n";


async function doit(){
 try { 
    var events = await ical.async.parseICS(myevents);
   } 
   catch(error){
 	console.log(error.message)
	events="error processing "+error.message
   }
   return events
}
console.log("Starting....");
try {
doit()
  .then((events) => {
    console.log("Finished....events=",JSON.stringify(events));
    process.exit(0);
  })
  .catch(err => {
    console.error(err);
    process.exit(1);
  });
}
catch(error){
  console.log(error.message)
}

this catches the throw in the current unmodified code

Finished....events= "error processing No toISOString function in curr.start"

@johnhundley
Copy link

johnhundley commented Oct 22, 2024

It's not an invalid RRULE, it has multiple events. I believe the issue is that it does not like Z as the timezone. Unfortunately I can not alter the format of the RRULE's I am given, they are coming from an external service. As mentioned it actually does work up to 0.12.6 - it parses the multiple events properly.

@sdetweil
Copy link
Contributor

sdetweil commented Oct 22, 2024

no, it has multiple DTSTART IN THE SAME/ONLY VEVENT, in that test pgm

MULTIPLE BEGIN:VEVENT...END:VEVENT are required for multiple events

this test case crashes cause the date 'object' is an array, oops

show me a valid testcase

@sdetweil
Copy link
Contributor

sdetweil commented Oct 22, 2024

I added END:VEVENT/BEGIN:VEVENT before the second DTSTART in the string above, and with my debugging code

Starting....
processing for  BEGIN
processing for  DTSTART
ctx[start]= undefined
storeValueParameter not array for  start
storeValueParameter not array for  datetype
processing for  DTEND
processing dtend, curr.start= 2023-01-05T19:15:00.000Z { tz: 'Etc/UTC' }
storeValueParameter not array for  end
processing for  RRULE
processing rrule= RRULE:FREQ=WEEKLY;INTERVAL=1
processing for  END
end curr.start= 2023-01-05T19:15:00.000Z { tz: 'Etc/UTC' }
curr.end= 2023-01-05T19:30:00.000Z { tz: 'Etc/UTC' }
push alarms after
processing for  BEGIN
processing for  DTSTART
ctx[start]= undefined
storeValueParameter not array for  start
storeValueParameter not array for  datetype
processing for  DTEND
processing dtend, curr.start= 2023-01-05T19:30:00.000Z { tz: 'Etc/UTC' }
storeValueParameter not array for  end
processing for  RRULE
processing rrule= RRULE:FREQ=WEEKLY;INTERVAL=1
processing for  END
end curr.start= 2023-01-05T19:30:00.000Z { tz: 'Etc/UTC' }
curr.end= 2023-01-05T19:45:00.000Z { tz: 'Etc/UTC' }
push alarms after
Finished....events= {"7921043d-32ad-4fff-a53c-f99f64a8b609":{"type":"VEVENT","params":[],"start":"2023-01-05T19:15:00.000Z","datetype":"date-time","end":"2023-01-05T19:30:00.000Z","rrule":{"_cache":{"all":false,"before":[],"after":[],"between":[]},"origOptions":{"tzid":"Etc/UTC","dtstart":"2023-01-05T19:15:00.000Z","freq":2,"interval":1},"options":{"freq":2,"dtstart":"2023-01-05T19:15:00.000Z","interval":1,"wkst":0,"count":null,"until":null,"tzid":"Etc/UTC","bysetpos":null,"bymonth":null,"bymonthday":[],"bynmonthday":[],"byyearday":null,"byweekno":null,"byweekday":[3],"bynweekday":null,"byhour":[19],"byminute":[15],"bysecond":[0],"byeaster":null}}},"0f126168-58b2-425e-a6aa-e8b73698e44b":{"type":"VEVENT","params":[],"start":"2023-01-05T19:30:00.000Z","datetype":"date-time","end":"2023-01-05T19:45:00.000Z","rrule":{"_cache":{"all":false,"before":[],"after":[],"between":[]},"origOptions":{"tzid":"Etc/UTC","dtstart":"2023-01-05T19:30:00.000Z","freq":2,"interval":1},"options":{"freq":2,"dtstart":"2023-01-05T19:30:00.000Z","interval":1,"wkst":0,"count":null,"until":null,"tzid":"Etc/UTC","bysetpos":null,"bymonth":null,"bymonthday":[],"bynmonthday":[],"byyearday":null,"byweekno":null,"byweekday":[3],"bynweekday":null,"byhour":[19],"byminute":[30],"bysecond":[0],"byeaster":null}}}}

no problems at all.

@sdetweil
Copy link
Contributor

sdetweil commented Oct 22, 2024

it 'worked' before 12.7 cause 12.7 replaced messages with throw, but the errors were there
Screenshot at 2024-10-22 11-01-00

@sdetweil
Copy link
Contributor

sdetweil commented Oct 22, 2024

and as for parsing correctly prior to 12.7.. removed my dup checks and returned the throw to console.log()
and got this

{
  "4c0d2545-02f1-4db3-a20f-3be63653af5e": {
    "type": "VEVENT",
    "params": [],
    "start": [   <----------------------------oops
      "2023-01-05T19:15:00.000Z",
      "2023-01-05T19:30:00.000Z"
    ],
    "datetype": [  <----------------------------oops
      "date-time",
      "date-time"
    ],
    "end": [  <----------------------------oops
      "2023-01-05T19:30:00.000Z",
      "2023-01-05T19:45:00.000Z"
    ],
    "rrule": {
      "_cache": {
        "all": false,
        "before": [],
        "after": [],
        "between": []
      },
      "origOptions": {
        "freq": 2,
        "interval": 1
      },
      "options": {
        "freq": 2,
        "dtstart": "2024-10-22T16:10:32.000Z",
        "interval": 1,
        "wkst": 0,
        "count": null,
        "until": null,
        "tzid": null,
        "bysetpos": null,
        "bymonth": null,
        "bymonthday": [],
        "bynmonthday": [],
        "byyearday": null,
        "byweekno": null,
        "byweekday": [
          1
        ],
        "bynweekday": null,
        "byhour": [
          16
        ],
        "byminute": [
          10
        ],
        "bysecond": [
          32
        ],
        "byeaster": null
      }
    }
  }
}

not parsed correctly
and with my logging

Starting....
processing for  BEGIN
processing for  DTSTART
ctx[start]= undefined
storeValueParameter not array for  start
storeValueParameter not array for  datetype
processing for  DTEND
processing dtend, curr.start= 2023-01-05T19:15:00.000Z { tz: 'Etc/UTC' }
storeValueParameter not array for  end
processing for  RRULE
processing rrule= RRULE:FREQ=WEEKLY;INTERVAL=1
processing for  DTSTART
ctx[start]= 2023-01-05T19:15:00.000Z { tz: 'Etc/UTC' }
storeValueParameter not array for  start
storeValueParameter not array for  datetype
processing for  DTEND
processing dtend, curr.start= [ <-------------------this array clearly cannot have a toISOString function
  2023-01-05T19:15:00.000Z { tz: 'Etc/UTC' },
  2023-01-05T19:30:00.000Z { tz: 'Etc/UTC' }
]
storeValueParameter not array for  end
processing for  RRULE
processing rrule= RRULE:FREQ=WEEKLY;INTERVAL=1
processing for  END
end curr.start= [
  2023-01-05T19:15:00.000Z { tz: 'Etc/UTC' },
  2023-01-05T19:30:00.000Z { tz: 'Etc/UTC' }
]
 not isostring     <---- was throw
curr.end= [
  2023-01-05T19:30:00.000Z { tz: 'Etc/UTC' },
  2023-01-05T19:45:00.000Z { tz: 'Etc/UTC' }
]
push alarms after
Finished....events= {"4c0d2545-02f1-4db3-a20f-3be63653af5e":{"type":"VEVENT","params":[],"start":["2023-01-05T19:15:00.000Z","2023-01-05T19:30:00.000Z"],"datetype":["date-time","date-time"],"end":["2023-01-05T19:30:00.000Z","2023-01-05T19:45:00.000Z"],"rrule":{"_cache":{"all":false,"before":[],"after":[],"between":[]},"origOptions":{"freq":2,"interval":1},"options":{"freq":2,"dtstart":"2024-10-22T16:10:32.000Z","interval":1,"wkst":0,"count":null,"until":null,"tzid":null,"bysetpos":null,"bymonth":null,"bymonthday":[],"bynmonthday":[],"byyearday":null,"byweekno":null,"byweekday":[1],"bynweekday":null,"byhour":[16],"byminute":[10],"bysecond":[32],"byeaster":null}}}}

correctly with two vevents, same dates and rrule

{
  "7921043d-32ad-4fff-a53c-f99f64a8b609": {
    "type": "VEVENT",
    "params": [],
    "start": "2023-01-05T19:15:00.000Z",
    "datetype": "date-time",
    "end": "2023-01-05T19:30:00.000Z",
    "rrule": {
      "_cache": {
        "all": false,
        "before": [],
        "after": [],
        "between": []
      },
      "origOptions": {
        "tzid": "Etc/UTC",
        "dtstart": "2023-01-05T19:15:00.000Z",
        "freq": 2,
        "interval": 1
      },
      "options": {
        "freq": 2,
        "dtstart": "2023-01-05T19:15:00.000Z",
        "interval": 1,
        "wkst": 0,
        "count": null,
        "until": null,
        "tzid": "Etc/UTC",
        "bysetpos": null,
        "bymonth": null,
        "bymonthday": [],
        "bynmonthday": [],
        "byyearday": null,
        "byweekno": null,
        "byweekday": [
          3
        ],
        "bynweekday": null,
        "byhour": [
          19
        ],
        "byminute": [
          15
        ],
        "bysecond": [
          0
        ],
        "byeaster": null
      }
    }
  },
  "0f126168-58b2-425e-a6aa-e8b73698e44b": {
    "type": "VEVENT",
    "params": [],
    "start": "2023-01-05T19:30:00.000Z",
    "datetype": "date-time",
    "end": "2023-01-05T19:45:00.000Z",
    "rrule": {
      "_cache": {
        "all": false,
        "before": [],
        "after": [],
        "between": []
      },
      "origOptions": {
        "tzid": "Etc/UTC",
        "dtstart": "2023-01-05T19:30:00.000Z",
        "freq": 2,
        "interval": 1
      },
      "options": {
        "freq": 2,
        "dtstart": "2023-01-05T19:30:00.000Z",
        "interval": 1,
        "wkst": 0,
        "count": null,
        "until": null,
        "tzid": "Etc/UTC",
        "bysetpos": null,
        "bymonth": null,
        "bymonthday": [],
        "bynmonthday": [],
        "byyearday": null,
        "byweekno": null,
        "byweekday": [
          3
        ],
        "bynweekday": null,
        "byhour": [
          19
        ],
        "byminute": [
          30
        ],
        "bysecond": [
          0
        ],
        "byeaster": null
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants