001/*
002 * (C) Copyright 2006-2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Bogdan Stefanescu
018 *     Florent Guillaume
019 */
020package org.nuxeo.ecm.core.api;
021
022import java.util.Collections;
023import java.util.LinkedList;
024import java.util.List;
025
026/**
027 * The most generic exception thrown by the Nuxeo.
028 * <p>
029 * It can be used to provide enriched information on the exception catch path, without re-wrapping:
030 *
031 * <pre>
032 * try {
033 *     doSomething(id);
034 * } catch (NuxeoException e) {
035 *     e.addInfo("Failed to do something with document id: " + id);
036 *     throw e;
037 * }
038 * </pre>
039 */
040public class NuxeoException extends RuntimeException {
041
042    private static final long serialVersionUID = 1L;
043
044    private LinkedList<String> infos;
045
046    public NuxeoException() {
047    }
048
049    public NuxeoException(String message) {
050        super(message);
051    }
052
053    public NuxeoException(String message, Throwable cause) {
054        super(message, cause);
055    }
056
057    public NuxeoException(Throwable cause) {
058        super(cause);
059    }
060
061    /**
062     * Adds information to this exception, to be returned with the message.
063     *
064     * @param info the information
065     * @since 7.4
066     */
067    public void addInfo(String info) {
068        if (infos == null) {
069            infos = new LinkedList<>();
070        }
071        infos.addFirst(info);
072    }
073
074    /**
075     * Gets the information added to this exception.
076     * <p>
077     * The list is returned in the reverse order than that of the calls to {@link #addInfo}, i.e., the last added
078     * information is first in the list.
079     *
080     * @return the information list
081     * @since 7.4
082     */
083    public List<String> getInfos() {
084        return infos == null ? Collections.emptyList() : infos;
085    }
086
087    /**
088     * Gets the original message passed to the constructor, without additional information added.
089     *
090     * @since 7.4
091     */
092    public String getOriginalMessage() {
093        return super.getMessage();
094    }
095
096    @Override
097    public String getMessage() {
098        String message = getOriginalMessage();
099        if (infos == null) {
100            return message;
101        } else {
102            StringBuilder sb = new StringBuilder();
103            for (String info : infos) {
104                sb.append(info);
105                sb.append(", ");
106            }
107            sb.append(message);
108            return sb.toString();
109        }
110    }
111
112}