Skip to content

Format Java Backend Exceptions#1777

Open
Mythicaeda wants to merge 27 commits into
developfrom
refactor/permissions-service-exceptions
Open

Format Java Backend Exceptions#1777
Mythicaeda wants to merge 27 commits into
developfrom
refactor/permissions-service-exceptions

Conversation

@Mythicaeda
Copy link
Copy Markdown
Contributor

@Mythicaeda Mythicaeda commented Feb 3, 2026

Description

This PR does three things:

  1. Make PermissionsService only throw a singular exception to reduce duplicated code in the services that use it
  2. Update how Exceptions thrown in the Java endpoints are formatted to be united.
  3. Ensure that Hasura returns the entire formatted exception in the extensions object

Number 2) is accomplished by pulling FormattedError out into the parsing-utils library, then creating service-specific subclasses to handle service-specific exceptions.

Verification

E2E Tests were updated to reflect the updates to the error messages.

I did some manual tests with the UI. In these tests, I started a debugger in the backend with a breakpoint set at the start of the Hasura Action Handler code. After submitting the request via the UI, I would go in and remove data from the database to force the backend pre-checks to fail. I'd then resume the backend and observe that 1) the backend was sending the information correctly and 2) how the UI was parsing the response.

What I observed was:

  • for Hasura Action endpoints, the backend is correctly putting the formatted exception in the extensions object
  • the UI is reading this extensions object and is able to extract data, service, and timestamp out of it. It's unclear if it's using the top-level message field or the one in the extensions object, but that doesn't matter since they contain the same string.
  • the UI is not reading the type field out of the extensions object, instead using a generic ERROR type. The type field is present in extensions object
  • if scheduling, simulation, or constraints throw an exception (rather than failing), the exception is placed under the generic LOGS tab rather than being sorted into the correct category.

Example:
Server Response:

{
	"errors": [
		{
			"extensions": {
				"data": {
					"specification_id": 659
				},
				"message": "Could not check permissions on scheduling specification 659: specification does not exist.",
				"service": "aerie_permissions",
				"timestamp": "2026-05-18T16:10:49.084229462Z",
				"trace": <TRACE REMOVED BY ME FOR CONCISENESS>,
				"type": "NO_SUCH_SCHEDULING_SPECIFICATION"
			},
			"message": "Could not check permissions on scheduling specification 659: specification does not exist."
		}
	]
}

UI Logs:
image

Documentation

Future work

@Mythicaeda Mythicaeda self-assigned this Feb 3, 2026
@Mythicaeda Mythicaeda requested a review from a team as a code owner February 3, 2026 21:56
@Mythicaeda Mythicaeda added the refactor A code change that neither fixes a bug nor adds a feature label Feb 3, 2026
@Mythicaeda Mythicaeda requested review from AaronPlave and removed request for JoelCourtney February 3, 2026 21:56
@Mythicaeda Mythicaeda force-pushed the refactor/permissions-service-exceptions branch from 783696a to 92374af Compare February 3, 2026 23:04
@dandelany
Copy link
Copy Markdown
Collaborator

@Mythicaeda will do some smoke testing of this against the current version of the UI to make sure the new message format is fully supported

@dandelany
Copy link
Copy Markdown
Collaborator

Discussed this one with @Mythicaeda yesterday and we realized that the endpoints used by Hasura queries (listed in deployment/hasura/metadata/actions.yaml) need to have their error payloads wrapped in the extensions structure as noted in #1732 (see "Endpoints accessed by Hasura Actions")

@dandelany dandelany force-pushed the refactor/permissions-service-exceptions branch from 1d4c1f7 to 0280ffd Compare March 23, 2026 18:29
Mythicaeda added 10 commits May 13, 2026 15:22
…PermissionsException

- rename "PermissionsServiceException" to "GraphQLServiceException" for clarity
- Update Workspaces to process single PermissionsException
…lidJsonEntityException

InvalidJsonException was only a wrapper around JsonParsingException
- Was just a wrapper around the `MissionModelLoader` version of the exception
- Removing it means the Interface MissionModelService does not have to import its implementation
SchedulingCompilationError.schedulingErrorJsonP.unparse(ex.errors));
}

public SchedulerFormattedError(DatabaseException ex) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this be a db exception or a scheduling exception since the service here is still the scheduler?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have it under the main service's exception because a DatabaseException is thrown specifically when the service has a networking issue with the DB. If there's an actual issue with the transaction (for example, no rows are returned from the lookup or an insert fails), then a different exception type is thrown (ie NoSuchPlanException, FailedInsertException).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh wait right, the service here is merlin server.. is it odd to be hitting scheduling (since that is where the request is ultimately running) and get "service = merlin, db exception"? Or is that the right way? I guess whatever it is we should be consistent about it when we have these interacting services (you likely already are doing this, just talking out loud).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh the service being MERLIN_SERVICE is a typo, lemme fix that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

publish Tells GH to publish docker images for this PR refactor A code change that neither fixes a bug nor adds a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reduce the Types of Exceptions PermissionsService throws Implement common HTTP error message formats for all Aerie services

3 participants