@@ -73,6 +73,8 @@ type FoundAlert = Prisma.Result<
7373 > ;
7474} ;
7575
76+ class SkipRetryError extends Error { }
77+
7678export class DeliverAlertService extends BaseService {
7779 public async call ( alertId : string ) {
7880 const alert : FoundAlert | null = await this . _prisma . projectAlert . findFirst ( {
@@ -136,22 +138,34 @@ export class DeliverAlertService extends BaseService {
136138 alert . failedAttempt = finishedAttempt ;
137139 }
138140
139- switch ( alert . channel . type ) {
140- case "EMAIL" : {
141- await this . #sendEmail( alert ) ;
142- break ;
143- }
144- case "SLACK" : {
145- await this . #sendSlack( alert ) ;
146- break ;
147- }
148- case "WEBHOOK" : {
149- await this . #sendWebhook( alert ) ;
150- break ;
141+ try {
142+ switch ( alert . channel . type ) {
143+ case "EMAIL" : {
144+ await this . #sendEmail( alert ) ;
145+ break ;
146+ }
147+ case "SLACK" : {
148+ await this . #sendSlack( alert ) ;
149+ break ;
150+ }
151+ case "WEBHOOK" : {
152+ await this . #sendWebhook( alert ) ;
153+ break ;
154+ }
155+ default : {
156+ assertNever ( alert . channel . type ) ;
157+ }
151158 }
152- default : {
153- assertNever ( alert . channel . type ) ;
159+ } catch ( error ) {
160+ if ( error instanceof SkipRetryError ) {
161+ logger . error ( "[DeliverAlert] Skipping retry" , {
162+ reason : error . message ,
163+ } ) ;
164+
165+ return ;
154166 }
167+
168+ throw error ;
155169 }
156170
157171 await this . _prisma . projectAlert . update ( {
@@ -617,7 +631,7 @@ export class DeliverAlertService extends BaseService {
617631 type : "section" ,
618632 text : {
619633 type : "mrkdwn" ,
620- text : `\`\`\` ${ error . stackTrace ?? error . message } \`\`\`` ,
634+ text : this . #wrapInCodeBlock ( error . stackTrace ?? error . message ) ,
621635 } ,
622636 } ,
623637 {
@@ -729,7 +743,7 @@ export class DeliverAlertService extends BaseService {
729743 type : "section" ,
730744 text : {
731745 type : "mrkdwn" ,
732- text : `\`\`\` ${ error . stackTrace ?? error . message } \`\`\`` ,
746+ text : this . #wrapInCodeBlock ( error . stackTrace ?? error . message ) ,
733747 } ,
734748 } ,
735749 {
@@ -829,7 +843,7 @@ export class DeliverAlertService extends BaseService {
829843 type : "section" ,
830844 text : {
831845 type : "mrkdwn" ,
832- text : `\`\`\` ${ preparedError . stack ?? preparedError . message } \`\`\`` ,
846+ text : this . #wrapInCodeBlock ( preparedError . stack ?? preparedError . message ) ,
833847 } ,
834848 } ,
835849 {
@@ -1010,6 +1024,14 @@ export class DeliverAlertService extends BaseService {
10101024 message,
10111025 } ) ;
10121026
1027+ if ( error . data . error === "invalid_blocks" ) {
1028+ logger . error ( "[DeliverAlert] Slack invalid blocks" , {
1029+ error,
1030+ } ) ;
1031+
1032+ throw new SkipRetryError ( "Slack invalid blocks" ) ;
1033+ }
1034+
10131035 throw new Error ( "Slack platform error" ) ;
10141036 }
10151037
@@ -1047,6 +1069,25 @@ export class DeliverAlertService extends BaseService {
10471069 } ;
10481070 }
10491071
1072+ #wrapInCodeBlock( text : string , maxLength = 3000 ) {
1073+ return `\`\`\`${ this . #truncateSlackText( text , maxLength - 10 ) } \`\`\`` ;
1074+ }
1075+
1076+ #truncateSlackText( text : string , length = 3000 ) {
1077+ if ( text . length > length ) {
1078+ logger . debug ( "[DeliverAlert] Truncating slack text" , {
1079+ length,
1080+ originalLength : text . length ,
1081+ } ) ;
1082+
1083+ const truncationSuffix = "\n\ntruncated - check dashboard for complete error message" ;
1084+
1085+ return text . slice ( 0 , length - truncationSuffix . length ) + truncationSuffix ;
1086+ }
1087+
1088+ return text ;
1089+ }
1090+
10501091 static async enqueue (
10511092 alertId : string ,
10521093 tx : PrismaClientOrTransaction ,
0 commit comments