doorbot icon indicating copy to clipboard operation
doorbot copied to clipboard

throw new TypeError('Parameter "url" must be a string, not ' + typeof url);

Open ahuestis opened this issue 5 years ago • 4 comments

I ran download-all.js and it ran for a while downloading 4,327 videos before getting the error below. I am about to look at this closer to see if I can figure it out. I know that there are more videos after this, but this might be about where there is a gap where several months ago a bunch of videos were deleted from the ring web portal.

url.js:103 throw new TypeError('Parameter "url" must be a string, not ' + typeof url); ^

TypeError: Parameter "url" must be a string, not undefined at Url.parse (url.js:103:11) at Object.urlParse [as parse] (url.js:97:13) at ring.recording (...RingVids\download-all.js:64:46) at simpleRequest (...RingVids\node_modules\doorbot\doorbot.js:357:13) at fetch (...RingVids\node_modules\doorbot\doorbot.js:176:17) at IncomingMessage.res.on (...RingVids\node_modules\doorbot\doorbot.js:125:17) at emitNone (events.js:111:20) at IncomingMessage.emit (events.js:208:7) at endReadableNT (_stream_readable.js:1064:12) at _combinedTickCallback (internal/process/next_tick.js:139:11)

ahuestis avatar Oct 14 '18 00:10 ahuestis

Looks like the recording URL is coming back as null here: https://github.com/davglass/doorbot/blob/master/examples/download-all.js#L62

davglass avatar Oct 15 '18 22:10 davglass

I'm able to reproduce this. I think it is because some of my cameras have a plan and others do not on my account. So on this line ring.recording(info.id, (e, recording) * e=API returned Status Code 403

To debug I added console log messages like this one console.log('info: ' + JSON.stringify(info))

        //First value is HistoryLimit, max return is 100 so I hardcoded 1000 to make sure this number is bigger than what the API returns
        ring.history(1000, olderthan, (e, history) => {
            const fetch = (info, callback) => {
                console.log('info: ' + JSON.stringify(info))
                
                ring.recording(info.id, (e, recording) => {
                    if (e != null) {
                        console.log('Error: ' + e)
                        return
                    }
                    //Calculate the filename we want this to be saved as
                    console.log('recording: ' + JSON.stringify(recording))
                    
                    const datea = dateFormat(info['created_at'],"yyyymmdd_HHMMssZ");
                    const partFilePath = url.parse(recording).pathname.substring(0,url.parse(recording).pathname.length - 4);
                    const parts = partFilePath.split('/');
                    const filePath = '/' + parts[1] + '/' + datea + '_' + parts[2] + '.mp4';
                    const file = path.join(base, '.', filePath);

This is the output (I removed potentially confidentail information):

info: {"id":"1234","created_at":"2018-12-19T13:54:31.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":656,"description":"CameraWithPlan"}}
info: {"id":"1235","created_at":"2018-12-19T13:44:18.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
info: {"id":"1236","created_at":"2018-12-19T13:07:32.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
info: {"id":"1237","created_at":"2018-12-19T13:03:15.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
info: {"id":"1238","created_at":"2018-12-19T12:08:42.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
info: {"id":"1239","created_at":"2018-12-19T12:05:45.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":656,"description":"CameraWithPlan"}}
info: {"id":"1240","created_at":"2018-12-19T12:05:07.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
info: {"id":"1241","created_at":"2018-12-19T12:03:00.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
info: {"id":"1242","created_at":"2018-12-19T12:01:12.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
info: {"id":"1243","created_at":"2018-12-19T12:00:07.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
Error: Error: API returned Status Code 403
Error: Error: API returned Status Code 403
Error: Error: API returned Status Code 403
Error: Error: API returned Status Code 403
Error: Error: API returned Status Code 403
Error: Error: API returned Status Code 403
recording: "https://ring-transcoded-videos.s3.amazonaws.com/833/1234.mp4?..."
Error: Error: API returned Status Code 403
recording: "https://ring-transcoded-videos.s3.amazonaws.com/833/1239.mp4?..."
Error: Error: API returned Status Code 403
Fetching file /private/tmp/doorbot/downloads/833/20181219_075431CST_1234.mp4
Fetching file /private/tmp/doorbot/downloads/833/20181219_060545CST_1239.mp4
Done writing /private/tmp/doorbot/downloads/833/20181219_060545CST_1239.mp4
info: {"id":"1244","created_at":"2018-12-19T00:25:10.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
Error: Error: API returned Status Code 403
Done writing /private/tmp/doorbot/downloads/833/20181219_075431CST_1234.mp4
info: {"id":"1245","created_at":"2018-12-19T00:20:42.000Z","answered":false,"events":[],"kind":"motion","favorite":false,"snapshot_url":"","recording":{"status":"ready"},"duration":0,"doorbot":{"id":370,"description":"NoPlanCamera"}}
Error: Error: API returned Status Code 403

Above the NoPlanCamera is my camera that does not store video. And the other CameraWithPlan does have video history. So I think the code just needs some simple error detection for this use case.

yepher avatar Dec 19 '18 16:12 yepher

I think this may be the solution to the issue. Add:

if (e != null) {
    console.log('Recording Error: ' + e)
    return callback();
}

After:

ring.history(1000, olderthan, (e, history) => {
            const fetch = (info, callback) => {
                ring.recording(info.id, (e, recording) => {
                        --->HERE
                              :
                              :
 

yepher avatar Dec 19 '18 16:12 yepher

Funny. I had fixed this a long time ago and just recently ran across it again. Thanks for the answer.

gbolcer avatar Oct 21 '20 19:10 gbolcer