Skip to content

Commit aaba2b5

Browse files
dordsor21NotMyFaultCopilot
authored
fix: improve error handling in backups (#4740)
* fix: improve error handling in backups - fixes #4460 * cleanup * Update Core/src/main/java/com/plotsquared/core/backup/Backup.java Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Alexander Brandes <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 02a65c8 commit aaba2b5

File tree

6 files changed

+170
-73
lines changed

6 files changed

+170
-73
lines changed

Core/src/main/java/com/plotsquared/core/backup/Backup.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package com.plotsquared.core.backup;
2020

21+
import org.apache.logging.log4j.LogManager;
22+
import org.apache.logging.log4j.Logger;
2123
import org.checkerframework.checker.nullness.qual.Nullable;
2224

2325
import java.io.IOException;
@@ -30,12 +32,14 @@
3032
*/
3133
public class Backup {
3234

35+
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Backup.class.getSimpleName());
36+
3337
private final BackupProfile owner;
3438
private final long creationTime;
3539
@Nullable
3640
private final Path file;
3741

38-
Backup(final BackupProfile owner, final long creationTime, final Path file) {
42+
Backup(final BackupProfile owner, final long creationTime, @Nullable final Path file) {
3943
this.owner = owner;
4044
this.creationTime = creationTime;
4145
this.file = file;
@@ -49,7 +53,7 @@ public void delete() {
4953
try {
5054
Files.deleteIfExists(file);
5155
} catch (final IOException e) {
52-
e.printStackTrace();
56+
LOGGER.error("Error deleting backup at {}", file, e);
5357
}
5458
}
5559
}

Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121
import com.google.inject.Inject;
2222
import com.google.inject.assistedinject.Assisted;
2323
import com.plotsquared.core.configuration.caption.TranslatableCaption;
24-
import com.plotsquared.core.player.ConsolePlayer;
24+
import com.plotsquared.core.exception.PlotSquaredException;
2525
import com.plotsquared.core.player.PlotPlayer;
2626
import com.plotsquared.core.plot.Plot;
2727
import com.plotsquared.core.plot.schematic.Schematic;
2828
import com.plotsquared.core.util.SchematicHandler;
2929
import com.plotsquared.core.util.task.RunnableVal;
3030
import com.plotsquared.core.util.task.TaskManager;
31-
import net.kyori.adventure.text.minimessage.MiniMessage;
31+
import org.apache.logging.log4j.LogManager;
32+
import org.apache.logging.log4j.Logger;
3233
import org.checkerframework.checker.nullness.qual.NonNull;
3334
import org.checkerframework.checker.nullness.qual.Nullable;
3435

@@ -51,7 +52,7 @@
5152
*/
5253
public class PlayerBackupProfile implements BackupProfile {
5354

54-
static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build();
55+
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + PlayerBackupProfile.class.getSimpleName());
5556

5657
private final UUID owner;
5758
private final Plot plot;
@@ -87,7 +88,7 @@ private static Path resolve(final @NonNull Path parent, final String child) {
8788
Files.createDirectory(path);
8889
}
8990
} catch (final Exception e) {
90-
e.printStackTrace();
91+
LOGGER.error("Error resolving {} from {}", child, parent, e);
9192
}
9293
return path;
9394
}
@@ -104,7 +105,7 @@ private static Path resolve(final @NonNull Path parent, final String child) {
104105
try {
105106
Files.createDirectories(path);
106107
} catch (IOException e) {
107-
e.printStackTrace();
108+
LOGGER.error("Error creating directory {}", path, e);
108109
return Collections.emptyList();
109110
}
110111
}
@@ -117,11 +118,11 @@ private static Path resolve(final @NonNull Path parent, final String child) {
117118
backups.add(
118119
new Backup(this, basicFileAttributes.creationTime().toMillis(), file));
119120
} catch (IOException e) {
120-
e.printStackTrace();
121+
LOGGER.error("Error getting attributes for file {} to create backup", file, e);
121122
}
122123
});
123124
} catch (IOException e) {
124-
e.printStackTrace();
125+
LOGGER.error("Error walking files from {}", path, e);
125126
}
126127
backups.sort(Comparator.comparingLong(Backup::getCreationTime).reversed());
127128
return (this.backupCache = backups);
@@ -133,18 +134,20 @@ private static Path resolve(final @NonNull Path parent, final String child) {
133134
public void destroy() {
134135
this.listBackups().whenCompleteAsync((backups, error) -> {
135136
if (error != null) {
136-
error.printStackTrace();
137+
LOGGER.error("Error while listing backups", error);
137138
}
138139
backups.forEach(Backup::delete);
139140
this.backupCache = null;
140141
});
141142
}
142143

143144
public @NonNull Path getBackupDirectory() {
144-
return resolve(resolve(
145-
resolve(backupManager.getBackupPath(), Objects.requireNonNull(plot.getArea().toString(), "plot area id")),
146-
Objects.requireNonNull(plot.getId().toDashSeparatedString(), "plot id")
147-
), Objects.requireNonNull(owner.toString(), "owner"));
145+
return resolve(
146+
resolve(
147+
resolve(backupManager.getBackupPath(), Objects.requireNonNull(plot.getArea().toString(), "plot area id")),
148+
Objects.requireNonNull(plot.getId().toDashSeparatedString(), "plot id")
149+
), Objects.requireNonNull(owner.toString(), "owner")
150+
);
148151
}
149152

150153
@Override
@@ -156,7 +159,8 @@ public void destroy() {
156159
backups.get(backups.size() - 1).delete();
157160
}
158161
final List<Plot> plots = Collections.singletonList(plot);
159-
final boolean result = this.schematicHandler.exportAll(plots, getBackupDirectory().toFile(),
162+
final boolean result = this.schematicHandler.exportAll(
163+
plots, getBackupDirectory().toFile(),
160164
"%world%-%id%-" + System.currentTimeMillis(), () ->
161165
future.complete(new Backup(this, System.currentTimeMillis(), null))
162166
);
@@ -180,7 +184,7 @@ public void destroy() {
180184
try {
181185
schematic = this.schematicHandler.getSchematic(backup.getFile().toFile());
182186
} catch (SchematicHandler.UnsupportedFormatException e) {
183-
e.printStackTrace();
187+
LOGGER.error("Unsupported format for backup {}", backup.getFile(), e);
184188
}
185189
if (schematic == null) {
186190
future.completeExceptionally(new IllegalArgumentException(
@@ -200,10 +204,9 @@ public void run(Boolean value) {
200204
if (value) {
201205
future.complete(null);
202206
} else {
203-
future.completeExceptionally(new RuntimeException(MINI_MESSAGE.escapeTags(
207+
future.completeExceptionally(new PlotSquaredException(
204208
TranslatableCaption
205-
.of("schematics.schematic_paste_failed")
206-
.getComponent(ConsolePlayer.getConsole()))));
209+
.of("schematics.schematic_paste_failed")));
207210
}
208211
}
209212
}

Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import net.kyori.adventure.text.Component;
3333
import net.kyori.adventure.text.minimessage.tag.Tag;
3434
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
35+
import org.apache.logging.log4j.LogManager;
36+
import org.apache.logging.log4j.Logger;
3537
import org.checkerframework.checker.nullness.qual.NonNull;
3638
import org.checkerframework.checker.nullness.qual.Nullable;
3739

@@ -47,6 +49,7 @@
4749
@Singleton
4850
public class SimpleBackupManager implements BackupManager {
4951

52+
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + SimpleBackupManager.class.getSimpleName());
5053
private final Path backupPath;
5154
private final boolean automaticBackup;
5255
private final int backupLimit;
@@ -112,7 +115,12 @@ public void automaticBackup(@Nullable PlotPlayer<?> player, final @NonNull Plot
112115
TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
113116
);
114117
}
115-
throwable.printStackTrace();
118+
LOGGER.error(
119+
"Error creating backup for plot {};{} and player {}",
120+
plot.getArea(),
121+
plot.getId(),
122+
player == null ? "null" : player.getName(), throwable
123+
);
116124
} else {
117125
if (player != null) {
118126
player.sendMessage(TranslatableCaption.of("backups.backup_automatic_finished"));
@@ -128,6 +136,7 @@ public boolean shouldAutomaticallyBackup() {
128136
return this.automaticBackup;
129137
}
130138

139+
@NonNull
131140
public Path getBackupPath() {
132141
return this.backupPath;
133142
}

Core/src/main/java/com/plotsquared/core/command/Backup.java

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.plotsquared.core.backup.NullBackupProfile;
2525
import com.plotsquared.core.backup.PlayerBackupProfile;
2626
import com.plotsquared.core.configuration.caption.TranslatableCaption;
27+
import com.plotsquared.core.exception.PlotSquaredException;
2728
import com.plotsquared.core.permissions.Permission;
2829
import com.plotsquared.core.player.PlotPlayer;
2930
import com.plotsquared.core.plot.Plot;
@@ -32,6 +33,8 @@
3233
import net.kyori.adventure.text.Component;
3334
import net.kyori.adventure.text.minimessage.tag.Tag;
3435
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
36+
import org.apache.logging.log4j.LogManager;
37+
import org.apache.logging.log4j.Logger;
3538
import org.checkerframework.checker.nullness.qual.NonNull;
3639

3740
import java.nio.file.Files;
@@ -57,6 +60,8 @@
5760
permission = "plots.backup")
5861
public final class Backup extends Command {
5962

63+
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Backup.class.getSimpleName());
64+
6065
private final BackupManager backupManager;
6166

6267
@Inject
@@ -326,20 +331,43 @@ public void load(
326331
if (backupProfile instanceof NullBackupProfile) {
327332
player.sendMessage(
328333
TranslatableCaption.of("backups.backup_impossible"),
329-
TagResolver.resolver("plot", Tag.inserting(
330-
TranslatableCaption.of("generic.generic_other").toComponent(player)
331-
))
334+
TagResolver.resolver(
335+
"plot", Tag.inserting(
336+
TranslatableCaption.of("generic.generic_other").toComponent(player)
337+
)
338+
)
332339
);
333340
} else {
334341
backupProfile.listBackups().whenComplete((backups, throwable) -> {
335342
if (throwable != null) {
343+
Component reason;
344+
if (throwable instanceof PlotSquaredException pe) {
345+
reason = pe.getCaption().toComponent(player);
346+
} else {
347+
reason = Component.text(throwable.getMessage());
348+
}
336349
player.sendMessage(
337350
TranslatableCaption.of("backups.backup_load_failure"),
338-
TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
351+
TagResolver.resolver("reason", Tag.inserting(reason))
352+
);
353+
LOGGER.error("Error loading player ({}) backup", player.getName(), throwable);
354+
return;
355+
}
356+
if (number < 1 || number > backups.size()) {
357+
player.sendMessage(
358+
TranslatableCaption.of("backups.backup_impossible"),
359+
TagResolver.resolver(
360+
"plot",
361+
Tag.inserting(TranslatableCaption
362+
.of("generic.generic_invalid_choice")
363+
.toComponent(player))
364+
)
339365
);
340-
throwable.printStackTrace();
341366
} else {
342-
if (number < 1 || number > backups.size()) {
367+
final com.plotsquared.core.backup.Backup backup =
368+
backups.get(number - 1);
369+
if (backup == null || backup.getFile() == null || !Files
370+
.exists(backup.getFile())) {
343371
player.sendMessage(
344372
TranslatableCaption.of("backups.backup_impossible"),
345373
TagResolver.resolver(
@@ -350,37 +378,23 @@ public void load(
350378
)
351379
);
352380
} else {
353-
final com.plotsquared.core.backup.Backup backup =
354-
backups.get(number - 1);
355-
if (backup == null || backup.getFile() == null || !Files
356-
.exists(backup.getFile())) {
357-
player.sendMessage(
358-
TranslatableCaption.of("backups.backup_impossible"),
359-
TagResolver.resolver(
360-
"plot",
361-
Tag.inserting(TranslatableCaption
362-
.of("generic.generic_invalid_choice")
363-
.toComponent(player))
364-
)
365-
);
366-
} else {
367-
CmdConfirm.addPending(player, "/plot backup load " + number,
368-
() -> backupProfile.restoreBackup(backup, player)
369-
.whenComplete((n, error) -> {
370-
if (error != null) {
371-
player.sendMessage(
372-
TranslatableCaption.of("backups.backup_load_failure"),
373-
TagResolver.resolver(
374-
"reason",
375-
Tag.inserting(Component.text(error.getMessage()))
376-
)
377-
);
378-
} else {
379-
player.sendMessage(TranslatableCaption.of("backups.backup_load_success"));
380-
}
381-
})
382-
);
383-
}
381+
CmdConfirm.addPending(
382+
player, "/plot backup load " + number,
383+
() -> backupProfile.restoreBackup(backup, player)
384+
.whenComplete((n, error) -> {
385+
if (error != null) {
386+
player.sendMessage(
387+
TranslatableCaption.of("backups.backup_load_failure"),
388+
TagResolver.resolver(
389+
"reason",
390+
Tag.inserting(Component.text(error.getMessage()))
391+
)
392+
);
393+
} else {
394+
player.sendMessage(TranslatableCaption.of("backups.backup_load_success"));
395+
}
396+
})
397+
);
384398
}
385399
}
386400
});
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* PlotSquared, a land and world management plugin for Minecraft.
3+
* Copyright (C) IntellectualSites <https://intellectualsites.com>
4+
* Copyright (C) IntellectualSites team and contributors
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
package com.plotsquared.core.exception;
20+
21+
import com.plotsquared.core.configuration.caption.Caption;
22+
import com.plotsquared.core.configuration.caption.LocaleHolder;
23+
24+
/**
25+
* Internal use only. Used to allow adventure captions to be used in an exception
26+
*
27+
* @since TODO
28+
*/
29+
public final class PlotSquaredException extends RuntimeException {
30+
31+
private final Caption caption;
32+
33+
/**
34+
* Create a new instance with the given caption
35+
*
36+
* @param caption caption
37+
*/
38+
public PlotSquaredException(Caption caption) {
39+
this.caption = caption;
40+
}
41+
42+
/**
43+
* Create a new instance with the given caption and cause
44+
*
45+
* @param caption caption
46+
* @param cause cause
47+
*/
48+
public PlotSquaredException(Caption caption, Exception cause) {
49+
super(cause);
50+
this.caption = caption;
51+
}
52+
53+
@Override
54+
public String getMessage() {
55+
return caption.getComponent(LocaleHolder.console());
56+
}
57+
58+
public Caption getCaption() {
59+
return caption;
60+
}
61+
62+
}

0 commit comments

Comments
 (0)