jackrabbit-oak-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jukka Zitting <jukka.zitt...@gmail.com>
Subject Re: Exception handling in oak-core
Date Fri, 27 Apr 2012 13:17:55 GMT
Hi,

Instead of discussing this in the abstract, how about we look at a few
concrete cases to see how those would be best handled?

For example here's what the JCR spec says that the Session.save()
method [1] can throw:

> AccessDeniedException - if any of the changes to be persisted would violate the access
> privileges of the this Session. Also thrown if any of the changes to be persisted would
> cause the removal of a node that is currently referenced by a REFERENCE property
> that this Session does not have read access to.
>
> ItemExistsException - if any of the changes to be persisted would be prevented by the
> presence of an already existing item in the workspace.
>
> ConstraintViolationException - if any of the changes to be persisted would violate
> a node type or restriction. Additionally, a repository may use this exception to
> enforce implementation- or configuration-dependent restrictions.
>
> InvalidItemStateException - if any of the changes to be persisted conflicts with
> a change already persisted through another session and the implementation is
> such that this conflict can only be detected at save-time and therefore was not
> detected earlier, at change-time.
>
> ReferentialIntegrityException - if any of the changes to be persisted would cause
> the removal of a node that is currently referenced by a REFERENCE property
> that this Session has read access to.
>
> VersionException - if the save would make a result in a change to persistent
> storage that would violate the read-only status of a checked-in node.
>
> LockException - if the save would result in a change to persistent storage
> that would violate a lock.
>
> NoSuchNodeTypeException - if the save would result in the addition of a node
> with an unrecognized node type.
>
> RepositoryException - if another error occurs.

Our current implementation of save only throws generic
RepositoryExceptions and doesn't handle possible RuntimeExceptions
thrown from below:

    public void save() throws RepositoryException {
        try {
            root.commit();
        } catch (CommitFailedException e) {
            throw new RepositoryException(e);
        }
    }

Here's how I'd fix this:

    public void save() throws RepositoryException {
        try {
            root.commit();
        } catch (CommitFailedException e) {
            RepositoryException re =
                exceptionMapper.getRepositoryException(e);
            if (re == null) {
                re = new RepositoryException("Failed to save transient
changes", e);
            }
            throw re;
        } catch (RuntimeException e) {
            throw new RepositoryException("Unexpected save() failure", e);
        }
    }

This approach avoids having to build JCR-level information into the
core Oak API or related exceptions. Instead the various validator
plugins that enforce JCR-level constraints and throw
CommitFailedExceptions when called by the core can later map those
exceptions to appropriate JCR exceptions. To do this, such a validator
plugin would implement both the Validator interface in oak-core and a
new ExceptionMapper interface in oak-jcr, and connect to those
extension points.

Such an approach is obviously more complicated than simply allowing
RepositoryExceptions either directly in the Oak API or wrapped into
other exceptions, but the benefit is added flexibility.

For example, a direct HTTP->Oak mapping for something like a
client-facing JSOP access point (i.e. JSOP with all the constraint
checks, etc. in place), could easily provide it's own ExceptionMapper
extension point that instead of first going through JCR exceptions
would allow a validator component to directly craft an appropriate
HTTP response based on the kind of problem that was encountered.

[1] http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Session.html#save()

BR,

Jukka Zitting

Mime
View raw message