@@ -44,7 +44,7 @@ function formatDate(date) {
44
44
45
45
const time = date . slice ( 11 , 16 )
46
46
const timeZone = date . slice ( 19 )
47
-
47
+
48
48
return formattedDate + " at " + time + " (UTC" + ( timeZone == "Z" ? "" : timeZone ) + ")"
49
49
}
50
50
@@ -132,39 +132,45 @@ function fetchSourceCalendars(sourceCalendarURLs){
132
132
for ( var source of sourceCalendarURLs ) {
133
133
var url = source [ 0 ] . replace ( "webcal://" , "https://" ) ;
134
134
var colorId = source [ 1 ] ;
135
-
136
- callWithBackoff ( function ( ) {
137
- var urlResponse = UrlFetchApp . fetch ( url , { 'validateHttpsCertificates' : false , 'muteHttpExceptions' : true } ) ;
138
- if ( urlResponse . getResponseCode ( ) == 200 ) {
139
- var icsContent = urlResponse . getContentText ( )
140
- const icsRegex = RegExp ( "(BEGIN:VCALENDAR.*?END:VCALENDAR)" , "s" )
141
- var urlContent = icsRegex . exec ( icsContent ) ;
142
- if ( urlContent == null ) {
143
- // Microsoft Outlook has a bug that sometimes results in incorrectly formatted ics files. This tries to fix that problem.
144
- // Add END:VEVENT for every BEGIN:VEVENT that's missing it
145
- const veventRegex = / B E G I N : V E V E N T (?: (? ! E N D : V E V E N T ) .) * ?(? = .B E G I N | .E N D : V C A L E N D A R | $ ) / sg;
146
- icsContent = icsContent . replace ( veventRegex , ( match ) => match + "\nEND:VEVENT" ) ;
147
-
148
- // Add END:VCALENDAR if missing
149
- if ( ! icsContent . endsWith ( "END:VCALENDAR" ) ) {
150
- icsContent += "\nEND:VCALENDAR" ;
151
- }
152
- urlContent = icsRegex . exec ( icsContent )
135
+
136
+ try {
137
+ callWithBackoff ( function ( ) {
138
+ var urlResponse = UrlFetchApp . fetch ( url , { 'validateHttpsCertificates' : false , 'muteHttpExceptions' : true } ) ;
139
+ if ( urlResponse . getResponseCode ( ) == 200 ) {
140
+ var icsContent = urlResponse . getContentText ( )
141
+ const icsRegex = RegExp ( "(BEGIN:VCALENDAR.*?END:VCALENDAR)" , "s" )
142
+ var urlContent = icsRegex . exec ( icsContent ) ;
153
143
if ( urlContent == null ) {
154
- Logger . log ( "[ERROR] Incorrect ics/ical URL: " + url )
155
- return
144
+ // Microsoft Outlook has a bug that sometimes results in incorrectly formatted ics files. This tries to fix that problem.
145
+ // Add END:VEVENT for every BEGIN:VEVENT that's missing it
146
+ const veventRegex = / B E G I N : V E V E N T (?: (? ! E N D : V E V E N T ) .) * ?(? = .B E G I N | .E N D : V C A L E N D A R | $ ) / sg;
147
+ icsContent = icsContent . replace ( veventRegex , ( match ) => match + "\nEND:VEVENT" ) ;
148
+
149
+ // Add END:VCALENDAR if missing
150
+ if ( ! icsContent . endsWith ( "END:VCALENDAR" ) ) {
151
+ icsContent += "\nEND:VCALENDAR" ;
152
+ }
153
+ urlContent = icsRegex . exec ( icsContent )
154
+ if ( urlContent == null ) {
155
+ Logger . log ( "[ERROR] Incorrect ics/ical URL: " + url )
156
+ reportOverallFailure = true ;
157
+ return
158
+ }
159
+ Logger . log ( "[WARNING] Microsoft is incorrectly formatting ics/ical at: " + url )
156
160
}
157
- Logger . log ( "[WARNING] Microsoft is incorrectly formatting ics/ical at: " + url )
161
+ result . push ( [ urlContent [ 0 ] , colorId ] ) ;
162
+ return ;
158
163
}
159
- result . push ( [ urlContent [ 0 ] , colorId ] ) ;
160
- return ;
161
- }
162
- else { //Throw here to make callWithBackoff run again
163
- throw "Error: Encountered HTTP error " + urlResponse . getResponseCode ( ) + " when accessing " + url ;
164
- }
165
- } , defaultMaxRetries ) ;
164
+ else { //Throw here to make callWithBackoff run again
165
+ throw "Error: Encountered HTTP error " + urlResponse . getResponseCode ( ) + " when accessing " + url ;
166
+ }
167
+ } , defaultMaxRetries ) ;
168
+ }
169
+ catch ( e ) {
170
+ reportOverallFailure = true ;
171
+ }
166
172
}
167
-
173
+
168
174
return result ;
169
175
}
170
176
@@ -242,7 +248,7 @@ function parseResponses(responses){
242
248
} ) ;
243
249
}
244
250
245
- //No need to process calcelled events as they will be added to gcal's trash anyway
251
+ //No need to process cancelled events as they will be added to gcal's trash anyway
246
252
result = result . filter ( function ( event ) {
247
253
try {
248
254
return ( event . getFirstPropertyValue ( 'status' ) . toString ( ) . toLowerCase ( ) != "cancelled" ) ;
@@ -436,7 +442,7 @@ function createEvent(event, calendarTz){
436
442
if ( organizerMail )
437
443
newEvent . organizer . email = organizerMail . toString ( ) ;
438
444
439
- if ( addOrganizerToTitle && organizerName ) {
445
+ if ( addOrganizerToTitle && organizerName ) {
440
446
newEvent . summary = organizerName + ": " + newEvent . summary ;
441
447
}
442
448
}
@@ -1090,7 +1096,14 @@ function sendSummary() {
1090
1096
var backoffRecoverableErrors = [
1091
1097
"service invoked too many times in a short time" ,
1092
1098
"rate limit exceeded" ,
1093
- "internal error" ] ;
1099
+ "internal error" ,
1100
+ "http error 403" , // forbidden
1101
+ "http error 408" , // request timeout
1102
+ "http error 423" , // locked
1103
+ "http error 500" , // internal server error
1104
+ "http error 503" , // service unavailable
1105
+ "http error 504" // gateway timeout
1106
+ ] ;
1094
1107
function callWithBackoff ( func , maxRetries ) {
1095
1108
var tries = 0 ;
1096
1109
var result ;
@@ -1102,10 +1115,7 @@ function callWithBackoff(func, maxRetries) {
1102
1115
}
1103
1116
catch ( err ) {
1104
1117
err = err . message || err ;
1105
- if ( err . includes ( "HTTP error" ) ) {
1106
- Logger . log ( err ) ;
1107
- return null ;
1108
- } else if ( err . includes ( "is not a function" ) || ! backoffRecoverableErrors . some ( function ( e ) {
1118
+ if ( err . includes ( "is not a function" ) || ! backoffRecoverableErrors . some ( function ( e ) {
1109
1119
return err . toLowerCase ( ) . includes ( e ) ;
1110
1120
} ) ) {
1111
1121
throw err ;
0 commit comments