Skip to content

Conversation

@tbonelee
Copy link
Contributor

@tbonelee tbonelee commented Oct 6, 2025

What is this PR for?

After #5090, we started hiding unhandled error details from clients, which caused some tests that depended on those details to fail. The afffected cases are note imports/creations that should fail when the target note path already exists.

This PR introduces a ConflictException and updates NotebookRestApi to return HTTP 409 (Conflict) when NotebookService throws or returns NotePathAlreadyExistsException.

I chose to do this exception-to-HTTP mapping in NotebookRestApi because NotebookService is also used outside REST contexts, and assigning HTTP status codes belongs in the REST layer.

What type of PR is it?

Bug Fix

What is the Jira issue?

https://issues.apache.org/jira/browse/ZEPPELIN-6356

How should this be tested?

  • Check if zeppelin-integration-test and other tests pass

Screenshots (if appropriate)

image

Questions:

  • Does the license files need to update? No
  • Is there breaking changes for older versions? No
  • Does this needs documentation? No

@tbonelee tbonelee requested a review from Reamer October 6, 2025 02:02
@tbonelee
Copy link
Contributor Author

tbonelee commented Oct 6, 2025

@Reamer When you have a moment, could you please take a look at this?

- Introduced `ConflictException` for detailed error response.
- Added handling of `NotePathAlreadyExistsException` in `NotebookRestApi`.
@tbonelee tbonelee force-pushed the fix-client-integration-test branch from 13cc043 to aa0c2e2 Compare October 7, 2025 11:15
Copy link
Contributor

@Reamer Reamer left a comment

Choose a reason for hiding this comment

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

I thought long and hard about how to solve this problem.
There are various exceptions in org.apache.zeppelin.rest.exception that inherit from WebApplicationException, and there are mappings in the code in various places. In my opinion, this is somewhat unnecessary, as we have an ExceptionMapper. It currently has an unattractive name, WebApplicationExceptionMapper, but it is a mapper for exceptions from the code to return a response.

I would rather solve the problem this way.

--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/exception/WebApplicationExceptionMapper.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/exception/WebApplicationExceptionMapper.java
@@ -22,18 +22,22 @@ import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.ext.ExceptionMapper;
 import jakarta.ws.rs.ext.Provider;
 
+import org.apache.zeppelin.notebook.exception.NotePathAlreadyExistsException;
+import org.apache.zeppelin.utils.ExceptionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Provider
 public class WebApplicationExceptionMapper implements ExceptionMapper<Throwable> {
-    
+
   private static final Logger LOGGER = LoggerFactory.getLogger(WebApplicationExceptionMapper.class);
 
   @Override
   public Response toResponse(Throwable exception) {
     if (exception instanceof WebApplicationException) {
       return ((WebApplicationException) exception).getResponse();
+    } else if (exception instanceof NotePathAlreadyExistsException) {
+      return ExceptionUtils.jsonResponseContent(Response.Status.CONFLICT, exception.getMessage());
     } else {
       LOGGER.error("Error response", exception);
       // Return generic error message to prevent information disclosure

@tbonelee tbonelee force-pushed the fix-client-integration-test branch 2 times, most recently from b07f794 to 69ebbf1 Compare October 9, 2025 06:43
@tbonelee tbonelee force-pushed the fix-client-integration-test branch from 69ebbf1 to 9a5cabf Compare October 9, 2025 06:43
@tbonelee
Copy link
Contributor Author

tbonelee commented Oct 9, 2025

Understood. So you prefer letting exceptions be thrown at the source and then handling them centrally in WebApplicationExceptionMapper wherever possible? I'm generally used to preventing service-layer exceptions from bubbling past the controller (except in unexpected cases), which is why I initially did it that way. But I don't have a strong preference.
I've updated the code as you suggested. Thanks for the thoughtful feedback!

Copy link
Contributor

@Reamer Reamer left a comment

Choose a reason for hiding this comment

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

All that's missing is the removal of an unnecessary class, otherwise it looks good to me. This change is, of course, a breaking change and will therefore only be merged into the master.

@Reamer
Copy link
Contributor

Reamer commented Oct 9, 2025

be thrown at the source and then handling them centrally in WebApplicationExceptionMapper wherever possible?

Yes, I hope this simplifies the code and leads to a uniform API response.

@tbonelee
Copy link
Contributor Author

tbonelee commented Oct 9, 2025

@Reamer I removed that class. I also realized I merged the previous PR, which caused the test failure, into branch-0.12. Since it is a breaking change, should I revert that commit to keep the 0.12 line stable? If you agree, I will open a revert PR targeting branch-0.12. Sorry for the oversight.

@tbonelee tbonelee requested a review from Reamer October 15, 2025 07:23
@tbonelee
Copy link
Contributor Author

I noticed the tests aren't fixed yet. I'll correct them and re-request review. Sorry for the confusion.

@Reamer
Copy link
Contributor

Reamer commented Oct 15, 2025

@Reamer I removed that class. I also realized I merged the previous PR, which caused the test failure, into branch-0.12. Since it is a breaking change, should I revert that commit to keep the 0.12 line stable? If you agree, I will open a revert PR targeting branch-0.12. Sorry for the oversight.

No, that's not necessary. We'll merge this change as well and accept the breaking change.

Copy link
Contributor

@Reamer Reamer left a comment

Choose a reason for hiding this comment

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

LGTM

@tbonelee tbonelee merged commit 33f35dc into apache:master Oct 19, 2025
19 checks passed
tbonelee added a commit that referenced this pull request Oct 19, 2025
### What is this PR for?

After #5090, we started hiding unhandled error details from clients, which caused some tests that depended on those details to fail. The afffected cases are note imports/creations that should fail when the target note path already exists.

This PR introduces a `ConflictException` and updates `NotebookRestApi` to return HTTP 409 (Conflict) when `NotebookService` throws or returns `NotePathAlreadyExistsException`.

I chose to do this exception-to-HTTP mapping in `NotebookRestApi` because `NotebookService` is also used outside REST contexts, and assigning HTTP status codes belongs in the REST layer.

### What type of PR is it?
Bug Fix

### What is the Jira issue?
https://issues.apache.org/jira/browse/ZEPPELIN-6356

### How should this be tested?
- Check if `zeppelin-integration-test` and other tests pass

### Screenshots (if appropriate)

<img width="1609" height="100" alt="image" src="https://github.com/user-attachments/assets/a445f36c-0267-42df-a75e-9f9f05f94964" />

### Questions:
* Does the license files need to update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No

Closes #5097 from tbonelee/fix-client-integration-test.

Signed-off-by: ChanHo Lee <[email protected]>
(cherry picked from commit 33f35dc)
Signed-off-by: ChanHo Lee <[email protected]>
@tbonelee tbonelee deleted the fix-client-integration-test branch October 19, 2025 11:48
@tbonelee
Copy link
Contributor Author

Thansk, I merged this into master and also the branch-0.12 as you suggested

dididy pushed a commit to dididy/zeppelin that referenced this pull request Oct 23, 2025
### What is this PR for?

After apache#5090, we started hiding unhandled error details from clients, which caused some tests that depended on those details to fail. The afffected cases are note imports/creations that should fail when the target note path already exists.

This PR introduces a `ConflictException` and updates `NotebookRestApi` to return HTTP 409 (Conflict) when `NotebookService` throws or returns `NotePathAlreadyExistsException`.

I chose to do this exception-to-HTTP mapping in `NotebookRestApi` because `NotebookService` is also used outside REST contexts, and assigning HTTP status codes belongs in the REST layer.


### What type of PR is it?
Bug Fix

### What is the Jira issue?
https://issues.apache.org/jira/browse/ZEPPELIN-6356

### How should this be tested?
- Check if `zeppelin-integration-test` and other tests pass

### Screenshots (if appropriate)

<img width="1609" height="100" alt="image" src="https://github.com/user-attachments/assets/a445f36c-0267-42df-a75e-9f9f05f94964" />


### Questions:
* Does the license files need to update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No


Closes apache#5097 from tbonelee/fix-client-integration-test.

Signed-off-by: ChanHo Lee <[email protected]>
dididy pushed a commit to dididy/zeppelin that referenced this pull request Oct 23, 2025
### What is this PR for?

After apache#5090, we started hiding unhandled error details from clients, which caused some tests that depended on those details to fail. The afffected cases are note imports/creations that should fail when the target note path already exists.

This PR introduces a `ConflictException` and updates `NotebookRestApi` to return HTTP 409 (Conflict) when `NotebookService` throws or returns `NotePathAlreadyExistsException`.

I chose to do this exception-to-HTTP mapping in `NotebookRestApi` because `NotebookService` is also used outside REST contexts, and assigning HTTP status codes belongs in the REST layer.


### What type of PR is it?
Bug Fix

### What is the Jira issue?
https://issues.apache.org/jira/browse/ZEPPELIN-6356

### How should this be tested?
- Check if `zeppelin-integration-test` and other tests pass

### Screenshots (if appropriate)

<img width="1609" height="100" alt="image" src="https://github.com/user-attachments/assets/a445f36c-0267-42df-a75e-9f9f05f94964" />


### Questions:
* Does the license files need to update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No


Closes apache#5097 from tbonelee/fix-client-integration-test.

Signed-off-by: ChanHo Lee <[email protected]>
dididy pushed a commit to dididy/zeppelin that referenced this pull request Oct 23, 2025
### What is this PR for?

After apache#5090, we started hiding unhandled error details from clients, which caused some tests that depended on those details to fail. The afffected cases are note imports/creations that should fail when the target note path already exists.

This PR introduces a `ConflictException` and updates `NotebookRestApi` to return HTTP 409 (Conflict) when `NotebookService` throws or returns `NotePathAlreadyExistsException`.

I chose to do this exception-to-HTTP mapping in `NotebookRestApi` because `NotebookService` is also used outside REST contexts, and assigning HTTP status codes belongs in the REST layer.


### What type of PR is it?
Bug Fix

### What is the Jira issue?
https://issues.apache.org/jira/browse/ZEPPELIN-6356

### How should this be tested?
- Check if `zeppelin-integration-test` and other tests pass

### Screenshots (if appropriate)

<img width="1609" height="100" alt="image" src="https://github.com/user-attachments/assets/a445f36c-0267-42df-a75e-9f9f05f94964" />


### Questions:
* Does the license files need to update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No


Closes apache#5097 from tbonelee/fix-client-integration-test.

Signed-off-by: ChanHo Lee <[email protected]>
dididy pushed a commit to dididy/zeppelin that referenced this pull request Oct 23, 2025
### What is this PR for?

After apache#5090, we started hiding unhandled error details from clients, which caused some tests that depended on those details to fail. The afffected cases are note imports/creations that should fail when the target note path already exists.

This PR introduces a `ConflictException` and updates `NotebookRestApi` to return HTTP 409 (Conflict) when `NotebookService` throws or returns `NotePathAlreadyExistsException`.

I chose to do this exception-to-HTTP mapping in `NotebookRestApi` because `NotebookService` is also used outside REST contexts, and assigning HTTP status codes belongs in the REST layer.


### What type of PR is it?
Bug Fix

### What is the Jira issue?
https://issues.apache.org/jira/browse/ZEPPELIN-6356

### How should this be tested?
- Check if `zeppelin-integration-test` and other tests pass

### Screenshots (if appropriate)

<img width="1609" height="100" alt="image" src="https://github.com/user-attachments/assets/a445f36c-0267-42df-a75e-9f9f05f94964" />


### Questions:
* Does the license files need to update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No


Closes apache#5097 from tbonelee/fix-client-integration-test.

Signed-off-by: ChanHo Lee <[email protected]>
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