Use @Slf4j in ReminderScheduler and Reminder, convert null checks to Optional, and enhance logging for error handling and unexpected channel types.

This commit is contained in:
akastijn 2026-07-12 22:24:03 +02:00
parent cbe13d3033
commit 59065dddc8
2 changed files with 65 additions and 41 deletions

View File

@ -1,12 +1,15 @@
package com.alttd.database.queries.QueriesReminders; package com.alttd.database.queries.QueriesReminders;
import com.alttd.util.Logger; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.Channel;
import org.jspecify.annotations.NonNull;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional;
@Slf4j
public record Reminder (int id, String title, String description, long userId, long guildId, long channelId, public record Reminder (int id, String title, String description, long userId, long guildId, long channelId,
long messageId, boolean shouldRepeat, long creationDate, long remindDate, ReminderType reminderType, byte[] data) { long messageId, boolean shouldRepeat, long creationDate, long remindDate, ReminderType reminderType, byte[] data) {
@ -26,34 +29,35 @@ public record Reminder (int id, String title, String description, long userId, l
reminder.data()); reminder.data());
} }
public Channel getChannel(JDA jda) { public Optional<Channel> getChannel(JDA jda) {
Guild guildById = getGuild(jda); Optional<Guild> optionalGuild = getGuild(jda);
if (guildById == null) if (optionalGuild.isEmpty())
return null; return Optional.empty();
Channel channelById = guildById.getTextChannelById(this.channelId); Guild guild = optionalGuild.get();
Channel channelById = guild.getTextChannelById(this.channelId);
if (channelById == null) if (channelById == null)
channelById = guildById.getThreadChannelById(this.channelId); channelById = guild.getThreadChannelById(this.channelId);
if (channelById == null) { if (channelById == null) {
Logger.altitudeLogs.warning("Unable to find text channel for reminder, text channel id: [" + channelId + "]"); log.warn("Unable to find text channel for reminder, text channel id: [{}]", channelId);
return null; return Optional.empty();
} }
return channelById; return Optional.of(channelById);
} }
public Guild getGuild(JDA jda) { public Optional<Guild> getGuild(JDA jda) {
Guild guildById = jda.getGuildById(guildId); Guild guildById = jda.getGuildById(guildId);
if (guildById == null) { if (guildById == null) {
Logger.altitudeLogs.warning("Unable to find guild for reminder, guild id: [" + guildId + "]"); log.warn("Unable to find guild for reminder, guild id: [{}]", guildId);
return null; return Optional.empty();
} }
return guildById; return Optional.of(guildById);
} }
@Override @Override
public String toString() { public @NonNull String toString() {
return "Reminder{" + return "Reminder{" +
"\nid=[" + id + "]" + "\nid=[" + id + "]" +
"\ntitle=[" + title + "]" + "\ntitle=[" + title + "]" +

View File

@ -4,6 +4,7 @@ import com.alttd.database.queries.QueriesReminders.QueriesReminders;
import com.alttd.database.queries.QueriesReminders.Reminder; import com.alttd.database.queries.QueriesReminders.Reminder;
import com.alttd.util.Logger; import com.alttd.util.Logger;
import com.alttd.util.Util; import com.alttd.util.Util;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
@ -20,10 +21,12 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.Optional;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Slf4j
public class ReminderScheduler { public class ReminderScheduler {
private static ReminderScheduler instance = null; private static ReminderScheduler instance = null;
@ -41,10 +44,11 @@ public class ReminderScheduler {
return; return;
} }
reminders.sort(Comparator.comparingLong(Reminder::remindDate)); reminders.sort(Comparator.comparingLong(Reminder::remindDate));
if (reminders.size() == 0) if (reminders.isEmpty()) {
nextReminder = null; nextReminder = null;
else } else {
nextReminder = reminders.get(0); nextReminder = reminders.getFirst();
}
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleWithFixedDelay(new ReminderRun(), 0, 1, TimeUnit.MINUTES); scheduledExecutorService.scheduleWithFixedDelay(new ReminderRun(), 0, 1, TimeUnit.MINUTES);
@ -63,19 +67,22 @@ public class ReminderScheduler {
} }
reminders.add(reminder); reminders.add(reminder);
reminders.sort(Comparator.comparingLong(Reminder::remindDate)); reminders.sort(Comparator.comparingLong(Reminder::remindDate));
nextReminder = reminders.get(0); nextReminder = reminders.getFirst();
} }
public synchronized void removeReminder(Reminder reminder, boolean removeFromDatabase) { public synchronized void removeReminder(Reminder reminder, boolean removeFromDatabase) {
Logger.altitudeLogs.debug("Removing reminder with messageId: " + reminder.messageId()); Logger.altitudeLogs.debug("Removing reminder with messageId: " + reminder.messageId());
reminders.remove(reminder); reminders.remove(reminder);
reminders.sort(Comparator.comparingLong(Reminder::remindDate)); reminders.sort(Comparator.comparingLong(Reminder::remindDate));
if (reminders.size() == 0) if (reminders.isEmpty()) {
nextReminder = null; nextReminder = null;
else } else {
nextReminder = reminders.get(0); nextReminder = reminders.getFirst();
if (removeFromDatabase) }
QueriesReminders.removeReminder(reminder); if (!removeFromDatabase) {
return;
}
QueriesReminders.removeReminder(reminder);
} }
public synchronized void removeReminder(long messageId) { public synchronized void removeReminder(long messageId) {
@ -92,13 +99,14 @@ public class ReminderScheduler {
public void run() { public void run() {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
while (nextReminder != null && time > nextReminder.remindDate()) { while (nextReminder != null && time > nextReminder.remindDate()) {
Channel channel = nextReminder.getChannel(jda); Optional<Channel> optionalChannel = nextReminder.getChannel(jda);
if (channel == null) { if (optionalChannel.isEmpty()) {
Logger.altitudeLogs.warning("Couldn't find channel, unable to run reminder: " + nextReminder.id() + Logger.altitudeLogs.warning("Couldn't find channel, unable to run reminder: " + nextReminder.id() +
"\ntitle: [" + nextReminder.title() + "\ntitle: [" + nextReminder.title() +
"]\ndescription: [" + nextReminder.description() + "]"); "]\ndescription: [" + nextReminder.description() + "]");
return; return;
} }
Channel channel = optionalChannel.get();
sendEmbed(nextReminder, channel); sendEmbed(nextReminder, channel);
if (nextReminder.shouldRepeat()) { if (nextReminder.shouldRepeat()) {
Reminder repeatedReminder = new Reminder( Reminder repeatedReminder = new Reminder(
@ -127,31 +135,38 @@ public class ReminderScheduler {
.setTitle(reminder.title()) .setTitle(reminder.title())
.setDescription(reminder.description()) .setDescription(reminder.description())
.appendDescription("\n\nRequested <t:" + TimeUnit.MILLISECONDS.toSeconds(reminder.creationDate()) + ":R>"); .appendDescription("\n\nRequested <t:" + TimeUnit.MILLISECONDS.toSeconds(reminder.creationDate()) + ":R>");
Guild guild = reminder.getGuild(jda); Optional<Guild> optionalGuild = reminder.getGuild(jda);
if (guild == null) { if (optionalGuild.isEmpty()) {
sendEmbed(reminder, channel, embedBuilder); sendEmbed(reminder, channel, embedBuilder);
return; return;
} }
Guild guild = optionalGuild.get();
guild.retrieveMemberById(reminder.userId()).queue( guild.retrieveMemberById(reminder.userId()).queue(
member -> sendEmbed(reminder, channel, embedBuilder, member), member -> sendEmbed(reminder, channel, embedBuilder, member),
failed -> sendEmbed(reminder, channel, embedBuilder)); failed -> sendEmbed(reminder, channel, embedBuilder));
} }
private MessageCreateAction getCreateAction(Channel channel, EmbedBuilder embedBuilder) { private Optional<MessageCreateAction> getCreateAction(Channel channel, EmbedBuilder embedBuilder) {
switch (channel.getType()) { return switch (channel.getType()) {
case TEXT, NEWS, FORUM -> { case TEXT, NEWS, FORUM -> {
if (channel instanceof TextChannel textChannel) { if (channel instanceof TextChannel textChannel) {
return textChannel.sendMessageEmbeds(embedBuilder.build()); yield Optional.of(textChannel.sendMessageEmbeds(embedBuilder.build()));
} }
Logger.altitudeLogs.warning("Received channel that is not a text channel " + channel.getType() + " can't send reminder...");
yield Optional.empty();
} }
case GUILD_NEWS_THREAD, GUILD_PUBLIC_THREAD, GUILD_PRIVATE_THREAD -> { case GUILD_NEWS_THREAD, GUILD_PUBLIC_THREAD, GUILD_PRIVATE_THREAD -> {
if (channel instanceof ThreadChannel threadChannel) { if (channel instanceof ThreadChannel threadChannel) {
return threadChannel.sendMessageEmbeds(embedBuilder.build()); yield Optional.of(threadChannel.sendMessageEmbeds(embedBuilder.build()));
} }
Logger.altitudeLogs.warning("Received thread that is not a guild thread " + channel.getType() + " can't send reminder...");
yield Optional.empty();
} }
default -> Logger.altitudeLogs.warning("Received unexpected channel type " + channel.getType() + " can't send reminder..."); case PRIVATE, VOICE, GROUP, CATEGORY, STAGE, MEDIA, GUILD_DIRECTORY, UNKNOWN -> {
} Logger.altitudeLogs.warning("Received unexpected channel type " + channel.getType() + " can't send reminder...");
return null; yield Optional.empty();
}
};
} }
private MessageCreateAction getCreateAction(Channel channel, String text) { private MessageCreateAction getCreateAction(Channel channel, String text) {
@ -175,9 +190,11 @@ public class ReminderScheduler {
embedBuilder.setAuthor(member.getEffectiveName(), null, member.getEffectiveAvatarUrl()); embedBuilder.setAuthor(member.getEffectiveName(), null, member.getEffectiveAvatarUrl());
switch (reminder.reminderType()) { switch (reminder.reminderType()) {
case NONE, MANUAL -> { case NONE, MANUAL -> {
MessageCreateAction createAction = getCreateAction(channel, embedBuilder); Optional<MessageCreateAction> optionalCreateAction = getCreateAction(channel, embedBuilder);
if (createAction == null) if (optionalCreateAction.isEmpty())
return; return;
MessageCreateAction createAction = optionalCreateAction.get();
createAction.queue(RestAction.getDefaultSuccess(), Util::handleFailure); createAction.queue(RestAction.getDefaultSuccess(), Util::handleFailure);
} }
case APPEAL -> { case APPEAL -> {
@ -189,12 +206,12 @@ public class ReminderScheduler {
try { try {
userId = dataInputStream.readLong(); userId = dataInputStream.readLong();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); log.error("Failed to read user id from reminder data", e);
} finally { } finally {
try { try {
dataInputStream.close(); dataInputStream.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); log.error("Failed to close data input stream", e);
} }
} }
MessageCreateAction messageCreateAction = getCreateAction(channel, "<@" + userId + ">"); MessageCreateAction messageCreateAction = getCreateAction(channel, "<@" + userId + ">");
@ -210,9 +227,12 @@ public class ReminderScheduler {
private void sendEmbed(Reminder reminder, Channel channel, EmbedBuilder embedBuilder) { private void sendEmbed(Reminder reminder, Channel channel, EmbedBuilder embedBuilder) {
embedBuilder.setAuthor(reminder.userId() + ""); embedBuilder.setAuthor(reminder.userId() + "");
MessageCreateAction createAction = getCreateAction(channel, embedBuilder); Optional<MessageCreateAction> optionalMessageCreateAction = getCreateAction(channel, embedBuilder);
if (createAction == null) if (optionalMessageCreateAction.isEmpty()) {
//Already logged
return; return;
}
MessageCreateAction createAction = optionalMessageCreateAction.get();
createAction.queue(RestAction.getDefaultSuccess(), Util::handleFailure); createAction.queue(RestAction.getDefaultSuccess(), Util::handleFailure);
} }
} }