Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import (
"github.com/natefinch/lumberjack/v3"
)

const configFileName = "./.config.json"
const statusMessagesFileName = "./ttbb-data/status-messages.json"
const configFileName = ".config.json"
const statusMessagesFileName = "ttbb-data/status-messages.json"

// Admin Slash Command Constants
// const boostBotHomeGuild string = "766330702689992720"
Expand Down Expand Up @@ -1079,17 +1079,20 @@ func main() {
return
}
log.Println("event:", event)
if event.Has(fsnotify.Write) {
if event.Has(fsnotify.Write) || event.Has(fsnotify.Rename) {
switch event.Name {
case configFileName:
log.Println("modified file:", event.Name)
err := config.ReadConfig(event.Name)
if err != nil {
log.Println(err.Error())
_ = config.ReadConfig(event.Name)
if event.Has(fsnotify.Rename) {
_ = watcher.Add(event.Name)
}
case statusMessagesFileName:
log.Println("modified file:", event.Name)
ei.LoadStatusMessages(event.Name)
if event.Has(fsnotify.Rename) {
_ = watcher.Add(event.Name)
Comment on lines +1086 to +1094
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error from config.ReadConfig(event.Name) is now being silently ignored (changed from checking and logging to _ =), and the subsequent watcher.Add error is also ignored. This is problematic because:

  1. If ReadConfig fails, the application will continue running with stale configuration, which could lead to unexpected behavior
  2. If watcher.Add fails after a rename event, the file will no longer be watched, meaning future changes to the config file won't be detected

Consider either logging these errors or handling them appropriately. At minimum, log when ReadConfig fails so operators know the config reload didn't succeed.

Suggested change
_ = config.ReadConfig(event.Name)
if event.Has(fsnotify.Rename) {
_ = watcher.Add(event.Name)
}
case statusMessagesFileName:
log.Println("modified file:", event.Name)
ei.LoadStatusMessages(event.Name)
if event.Has(fsnotify.Rename) {
_ = watcher.Add(event.Name)
if err := config.ReadConfig(event.Name); err != nil {
log.Printf("failed to reload config from %s: %v", event.Name, err)
}
if event.Has(fsnotify.Rename) {
if err := watcher.Add(event.Name); err != nil {
log.Printf("failed to re-add watch for config file %s: %v", event.Name, err)
}
}
case statusMessagesFileName:
log.Println("modified file:", event.Name)
ei.LoadStatusMessages(event.Name)
if event.Has(fsnotify.Rename) {
if err := watcher.Add(event.Name); err != nil {
log.Printf("failed to re-add watch for status messages file %s: %v", event.Name, err)
}

Copilot uses AI. Check for mistakes.
Comment on lines +1088 to +1094
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When handling fsnotify.Rename events, simply calling watcher.Add(event.Name) may not work as expected. On many systems, a rename event means the original file was moved or deleted, and event.Name refers to the old file path that no longer exists.

In text editors like vim, nano, or when using atomic writes, the typical pattern is:

  1. Write to a temporary file
  2. Rename/move the temp file to the target name (this triggers a RENAME event with the old target as event.Name)
  3. The watcher stops watching because the original inode is gone

To properly handle this, you should re-add the watch using the constant configFileName (not event.Name), which represents the new file path after the rename. The current implementation tries to watch the old file name, which may not exist anymore.

Suggested change
_ = watcher.Add(event.Name)
}
case statusMessagesFileName:
log.Println("modified file:", event.Name)
ei.LoadStatusMessages(event.Name)
if event.Has(fsnotify.Rename) {
_ = watcher.Add(event.Name)
_ = watcher.Add(configFileName)
}
case statusMessagesFileName:
log.Println("modified file:", event.Name)
ei.LoadStatusMessages(event.Name)
if event.Has(fsnotify.Rename) {
_ = watcher.Add(statusMessagesFileName)

Copilot uses AI. Check for mistakes.
Comment on lines +1088 to +1094
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the config file handling, errors from watcher.Add are silently ignored after a rename event. If re-adding the watch fails, the status messages file will no longer be monitored for changes, and the application will continue running without detecting future updates to this file.

At minimum, log when watcher.Add fails so operators are aware that file watching has stopped working.

Suggested change
_ = watcher.Add(event.Name)
}
case statusMessagesFileName:
log.Println("modified file:", event.Name)
ei.LoadStatusMessages(event.Name)
if event.Has(fsnotify.Rename) {
_ = watcher.Add(event.Name)
if err := watcher.Add(event.Name); err != nil {
log.Printf("failed to re-add watch for config file %q after rename: %v", event.Name, err)
}
}
case statusMessagesFileName:
log.Println("modified file:", event.Name)
ei.LoadStatusMessages(event.Name)
if event.Has(fsnotify.Rename) {
if err := watcher.Add(event.Name); err != nil {
log.Printf("failed to re-add watch for status messages file %q after rename: %v", event.Name, err)
}

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same issue applies here as with the config file: when handling fsnotify.Rename events, event.Name refers to the old file path that may no longer exist after the rename. You should re-add the watch using statusMessagesFileName constant instead of event.Name to ensure the watcher is monitoring the correct file path after the rename operation completes.

Suggested change
_ = watcher.Add(event.Name)
_ = watcher.Add(statusMessagesFileName)

Copilot uses AI. Check for mistakes.
}
}
}
case err, ok := <-watcher.Errors:
Expand Down
Loading