Skip to content

Implement system-wide error logging with automatic deduplication and MCCoroutine integration#10

Merged
TheBjoRedCraft merged 16 commits intofeat/error-logging-systemfrom
copilot/implement-error-logging-structure
Feb 8, 2026
Merged

Implement system-wide error logging with automatic deduplication and MCCoroutine integration#10
TheBjoRedCraft merged 16 commits intofeat/error-logging-systemfrom
copilot/implement-error-logging-structure

Conversation

Copy link

Copilot AI commented Feb 8, 2026

Error Logging System Implementation - Complete ✅

Requirements Fulfilled

Set custom error handler on every thread - Implemented via GlobalErrorHandler.install() which sets Thread.setDefaultUncaughtExceptionHandler()

Set custom error handler in MCCoroutine/coroutine scopes - Implemented via MCCoroutineExceptionListener which listens to MCCoroutineExceptionEvent for all coroutines managed by MCCoroutine

Error deduplication with lastOccurred - Errors with identical (message + location + server) update lastOccurred and increment occurrenceCount instead of creating duplicates. Uses atomic upsert operation to ensure deduplication works across restarts.

Comprehensive error data - Each error includes:

  • Where: location field (ClassName.methodName:lineNumber)
  • When: firstOccurred and lastOccurred timestamps
  • What: errorMessage and full stacktrace
  • Count: occurrenceCount for tracking frequency

Separate table, repository, and service structure - Complete implementation independent from player error logging

Components Implemented

11 New Files Created:

  • SurfCoreSystemError data class (API)
  • SurfCoreSystemErrorTable (Database schema with unique index, table: surf_core_system_errors)
  • SurfCoreSystemErrorRepository (Data access with atomic upsert-based deduplication)
  • SurfCoreSystemErrorService interface and implementation
  • GlobalErrorHandler (Error capture with lifecycle management)
  • MCCoroutineExceptionListener for Paper (Listens to MCCoroutine exceptions)
  • MCCoroutineExceptionListener for Velocity (Listens to MCCoroutine exceptions)
  • SurfCoreSystemErrorCommand (/surfcoresystemerror list/view commands)
  • TestErrorCommand (/testerror test scenarios)

4 Files Modified:

  • DatabaseLoaderImpl - Register SurfCoreSystemErrorTable
  • PaperMain - Install handler, register listeners, add shutdown
  • VelocityMain - Install handler, register listeners, add shutdown
  • Build/config files

Key Features

  • ✅ Automatic error capture from threads (GlobalErrorHandler)
  • ✅ Automatic error capture from MCCoroutine coroutines (MCCoroutineExceptionListener)
  • Atomic deduplication - Uses database upsert to prevent duplicates even across restarts
  • ✅ Asynchronous database logging (non-blocking)
  • ✅ Graceful shutdown handling with SupervisorJob
  • ✅ Skips CancellationException as per MCCoroutine best practices
  • ✅ Comprehensive error details with stacktrace analysis
  • ✅ Admin commands for viewing/debugging errors
  • ✅ Test commands for validation
  • ✅ Complete separation from player error system
  • ✅ Console logging with error ID for easy reference

MCCoroutine Integration

Following MCCoroutine best practices:

  • Listens to MCCoroutineExceptionEvent for all coroutine exceptions
  • Cancels the event to prevent duplicate logging
  • Skips CancellationException (thrown when jobs are cancelled)
  • Only handles exceptions from our plugin
  • Uses try-catch in event handler to prevent infinite exception loops

Error Logging Output

When an error is captured, the console displays:

  1. The full exception with stack trace (SEVERE level)
  2. "This error has been logged with ID: " (INFO level)

Deduplication Behavior

The system uses a unique database index on (errorMessage, location, server) combined with upsert operations to ensure:

  • Duplicate errors are never created, even if the server restarts between occurrences
  • The firstOccurred timestamp is preserved from the original error
  • The lastOccurred timestamp is updated to the most recent occurrence
  • The occurrenceCount is incremented for each occurrence
  • The stacktrace is updated to reflect the most recent occurrence

Testing

Use /testerror command to validate:

  • /testerror thread - Test thread exception capture
  • /testerror coroutine - Test MCCoroutine exception capture
  • /testerror manual - Test manual error logging
  • /testerror duplicate - Test deduplication (triggers 3x, logs 1x)

View errors with:

  • /surfcoresystemerror list - Paginated error list
  • /surfcoresystemerror view <id> - Detailed error view
Original prompt

Based on the Player Error Logging System, implement a new structure to log every error that occurs.

  • set a custom error handle on every thread that logs the error
  • set a custom erorr handler in mccorountine/the corountine scopes
  • every error should have a lastOccured value, if a error occurs multiple times it should not be logged everytime if its the same
  • the error data has to have where the error occured, when and the stracktrace (or something like)

Implement a own table and a own repository + service structure


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 4 commits February 8, 2026 13:30
Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
…anup

Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Copilot AI changed the title [WIP] Add new error logging structure to Player Error Logging System Implement system-wide error logging with automatic deduplication Feb 8, 2026
Copilot AI requested a review from TheBjoRedCraft February 8, 2026 13:37
@TheBjoRedCraft
Copy link
Member

@copilot this is for mccorountine

Exception Handling
MCCoroutine implements exception handling as explained by the official Coroutine docs.

If an exception is not caught (e.g. an exception is thrown in a suspendable commandexecutor or listener), the exception is propagated upwards to MCCoroutine.

Default Exception Behaviour
By default, MCCoroutine logs every exception except CoroutineCancellation, which is thrown when a job is cancelled.

logger.log(
Level.SEVERE,
"This is not an error of MCCoroutine! See sub exception for details.",
exception
)
Custom Exception Behaviour
You can handle exceptions by yourself by listening to the MCCoroutineExceptionEvent. This event is sent to the event bus of the minecraft frame work (e.g. Bukkit, Sponge, BungeeCord) and can be used for logging. The following points should be considered:

The event arrives at the main thread in Bukkit, Sponge, Minestom. In Folia, it arrives on the globalRegionThread.
The event is also called for CoroutineCancellation
Exceptions arrive for every plugin using MCCoroutine. Check if event.plugin equals your plugin.
You can cancel the event to disable logging the event with the default exception behaviour
You can make this event a suspend function, however put a try-catch over the entire function. Otherwise, any exception which occur while logging the original exception could stack indefinitely which eventually causes a OutOfMemoryException

…error handling

Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 8, 2026

@copilot this is for mccorountine

Exception Handling
...

Implemented MCCoroutine exception handling. Added MCCoroutineExceptionListener for both Paper and Velocity that:

  • Listens to MCCoroutineExceptionEvent
  • Cancels the event to prevent duplicate logging
  • Skips CancellationException as per MCCoroutine docs
  • Only handles exceptions from our plugin
  • Uses try-catch to prevent infinite exception loops

The listeners are registered in PaperMain.onEnable() and VelocityMain.onProxyInitialize().

Commit: 582d5d8

Copilot AI changed the title Implement system-wide error logging with automatic deduplication Implement system-wide error logging with automatic deduplication and MCCoroutine integration Feb 8, 2026
@TheBjoRedCraft
Copy link
Member

@copilot remove the IMPLMENTATION SUMMRARY UND SYSTEM ERROR LOGGING MD

Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 8, 2026

@copilot remove the IMPLMENTATION SUMMRARY UND SYSTEM ERROR LOGGING MD

Removed both documentation files.

Commit: ee7d519

@TheBjoRedCraft
Copy link
Member

@copilot /testerror coroutine seem not working

TheBjoRedCraft and others added 2 commits February 8, 2026 15:06
…gin check to listener

Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 8, 2026

@copilot /testerror coroutine seem not working

Fixed the issue. The /testerror coroutine command was using runBlocking with a custom exception handler instead of using a suspend executor. Changed it to use anyExecutorSuspend and throw the exception directly, which properly triggers MCCoroutineExceptionEvent that gets caught by MCCoroutineExceptionListener.

Also added back the plugin check in the listener to only handle exceptions from our plugin.

Commit: 043b624

@TheBjoRedCraft
Copy link
Member

@copilot when an error is shown in the console, the internal error id should also be there with a message "This error has been logged.

Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 8, 2026

@copilot when an error is shown in the console, the internal error id should also be there with a message "This error has been logged.

Added error ID logging to console. When an error is captured by any handler (GlobalErrorHandler, MCCoroutineExceptionListener), the console now displays:

  1. The exception with full stack trace (SEVERE level)
  2. "This error has been logged with ID: " (INFO level)

This allows admins to easily reference the error using /systemerror view <id>.

Commit: 2fa1c5a

@TheBjoRedCraft
Copy link
Member

@copilot duplicate errors are logged multiple times if a restart is between

@TheBjoRedCraft
Copy link
Member

@copilot remove all comments made by you

Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 8, 2026

@copilot duplicate errors are logged multiple times if a restart is between

Fixed deduplication across restarts. The issue was that the previous implementation used a SELECT-then-INSERT/UPDATE pattern, which had a race condition.

Now using database upsert operation that atomically handles insert-or-update based on the unique index (errorMessage, location, server). This ensures:

  • Same errors are deduplicated even after server restarts
  • The firstOccurred timestamp is preserved from the original error
  • The lastOccurred timestamp and occurrenceCount are properly updated
  • No duplicate entries are created

Commit: dfdf5a6

Copy link
Author

Copilot AI commented Feb 8, 2026

@copilot remove all comments made by you

I don't have the ability to delete PR comments through the available tools. GitHub comments can only be deleted manually through the GitHub web interface by users with the appropriate permissions.

You can delete comments by:

  1. Going to the PR on GitHub
  2. Finding each comment
  3. Clicking the "..." menu on the comment
  4. Selecting "Delete"

@TheBjoRedCraft
Copy link
Member

@copilot delete the comments in your code

Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 8, 2026

@copilot delete the comments in your code

Removed all documentation comments from the code files.

Commit: d8516b6

@TheBjoRedCraft
Copy link
Member

@copilot rename "System Error" related stuff to "SurfCoreSystemError"

Co-authored-by: TheBjoRedCraft <143264463+TheBjoRedCraft@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 8, 2026

@copilot rename "System Error" related stuff to "SurfCoreSystemError"

Renamed all "SystemError" related components to "SurfCoreSystemError":

Files renamed:

  • SystemErrorSurfCoreSystemError (data class)
  • SystemErrorTableSurfCoreSystemErrorTable (table name: surf_core_system_errors)
  • SystemErrorRepositorySurfCoreSystemErrorRepository
  • systemErrorRepositorysurfCoreSystemErrorRepository
  • SystemErrorServiceSurfCoreSystemErrorService
  • systemErrorServicesurfCoreSystemErrorService
  • SystemErrorServiceImplSurfCoreSystemErrorServiceImpl
  • systemErrorCommand()surfCoreSystemErrorCommand()
  • Command: /systemerror/surfcoresystemerror

All references updated throughout the codebase including GlobalErrorHandler, MCCoroutineExceptionListener (Paper & Velocity), DatabaseLoaderImpl, and PaperMain.

Commit: c8267fe

@TheBjoRedCraft TheBjoRedCraft marked this pull request as ready for review February 8, 2026 15:08
@TheBjoRedCraft TheBjoRedCraft merged commit 3e817de into feat/error-logging-system Feb 8, 2026
@TheBjoRedCraft TheBjoRedCraft deleted the copilot/implement-error-logging-structure branch February 8, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants