fix(server): avoid job fail if mail is not configured (#12306)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Improved email notification handling to prevent errors from interrupting other processes when sending emails is not possible.
- **Refactor**
  - Updated internal email sending logic across notifications and workspace features for more robust operation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
forehalo
2025-05-20 02:49:49 +00:00
parent acce1fbd99
commit 42d527251a
6 changed files with 33 additions and 19 deletions

View File

@@ -10,13 +10,20 @@ export class Mailer {
private readonly sender: MailSender
) {}
get enabled() {
// @ts-expect-error internal api
return this.sender.smtp !== null;
/**
* try to send mail
*
* @note never throw
*/
async trySend(command: Jobs['notification.sendMail']) {
return this.send(command, true);
}
async send(command: Jobs['notification.sendMail']) {
if (!this.enabled) {
async send(command: Jobs['notification.sendMail'], suppressError = false) {
if (!this.sender.configured) {
if (suppressError) {
return false;
}
throw new EmailServiceNotConfigured();
}

View File

@@ -43,6 +43,10 @@ export class MailSender {
return createTransport(configToSMTPOptions(config));
}
get configured() {
return this.smtp !== null;
}
@OnEvent('config.init')
onConfigInit() {
this.setup();

View File

@@ -65,7 +65,7 @@ export class NotificationService {
elementId: input.body.doc.elementId,
})
);
await this.mailer.send({
await this.mailer.trySend({
name: 'Mention',
to: receiver.email,
props: {
@@ -110,7 +110,7 @@ export class NotificationService {
if (!receiver) {
return;
}
await this.mailer.send({
await this.mailer.trySend({
name: 'MemberInvitation',
to: receiver.email,
props: {
@@ -161,7 +161,7 @@ export class NotificationService {
if (!inviter) {
return;
}
await this.mailer.send({
await this.mailer.trySend({
name: 'MemberAccepted',
to: inviter.email,
props: {
@@ -226,7 +226,7 @@ export class NotificationService {
if (!reviewer) {
return;
}
await this.mailer.send({
await this.mailer.trySend({
name: 'LinkInvitationReviewRequest',
to: reviewer.email,
props: {
@@ -273,7 +273,7 @@ export class NotificationService {
if (!receiver) {
return;
}
await this.mailer.send({
await this.mailer.trySend({
name: 'LinkInvitationApprove',
to: receiver.email,
props: {
@@ -312,7 +312,7 @@ export class NotificationService {
if (!receiver) {
return;
}
await this.mailer.send({
await this.mailer.trySend({
name: 'LinkInvitationDecline',
to: receiver.email,
props: {

View File

@@ -65,7 +65,7 @@ export class WorkspaceEvents {
return;
}
await this.mailer.send({
await this.mailer.trySend({
name: 'MemberRemoved',
to: user.email,
props: {

View File

@@ -107,7 +107,7 @@ export class WorkspaceService {
const admins = await this.models.workspaceUser.getAdmins(workspaceId);
const link = this.url.link(`/workspace/${workspaceId}`);
await this.mailer.send({
await this.mailer.trySend({
name: 'TeamWorkspaceUpgraded',
to: owner.email,
props: {
@@ -121,7 +121,7 @@ export class WorkspaceService {
await Promise.allSettled(
admins.map(async user => {
await this.mailer.send({
await this.mailer.trySend({
name: 'TeamWorkspaceUpgraded',
to: user.email,
props: {
@@ -188,7 +188,7 @@ export class WorkspaceService {
}
if (ws.role === WorkspaceRole.Admin) {
await this.mailer.send({
await this.mailer.trySend({
name: 'TeamBecomeAdmin',
to: user.email,
props: {
@@ -199,7 +199,7 @@ export class WorkspaceService {
},
});
} else {
await this.mailer.send({
await this.mailer.trySend({
name: 'TeamBecomeCollaborator',
to: user.email,
props: {
@@ -213,7 +213,7 @@ export class WorkspaceService {
}
async sendOwnershipTransferredEmail(email: string, ws: { id: string }) {
await this.mailer.send({
await this.mailer.trySend({
name: 'OwnershipTransferred',
to: email,
props: {
@@ -225,7 +225,7 @@ export class WorkspaceService {
}
async sendOwnershipReceivedEmail(email: string, ws: { id: string }) {
await this.mailer.send({
await this.mailer.trySend({
name: 'OwnershipReceived',
to: email,
props: {
@@ -238,7 +238,7 @@ export class WorkspaceService {
async sendLeaveEmail(workspaceId: string, userId: string) {
const owner = await this.models.workspaceUser.getOwner(workspaceId);
await this.mailer.send({
await this.mailer.trySend({
name: 'MemberLeave',
to: owner.email,
props: {