001/*
002 * Copyright (c) 2006-2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Bogdan Stefanescu
011 *     Florent Guillaume
012 */
013package org.nuxeo.ecm.core.api;
014
015import java.util.Collections;
016import java.util.LinkedList;
017import java.util.List;
018
019/**
020 * The most generic exception thrown by the Nuxeo.
021 * <p>
022 * It can be used to provide enriched information on the exception catch path, without re-wrapping:
023 *
024 * <pre>
025 * try {
026 *     doSomething(id);
027 * } catch (NuxeoException e) {
028 *     e.addInfo("Failed to do something with document id: " + id);
029 *     throw e;
030 * }
031 * </pre>
032 */
033public class NuxeoException extends RuntimeException {
034
035    private static final long serialVersionUID = 1L;
036
037    private LinkedList<String> infos;
038
039    public NuxeoException() {
040    }
041
042    public NuxeoException(String message) {
043        super(message);
044    }
045
046    public NuxeoException(String message, Throwable cause) {
047        super(message, cause);
048    }
049
050    public NuxeoException(Throwable cause) {
051        super(cause);
052    }
053
054    /**
055     * Adds information to this exception, to be returned with the message.
056     *
057     * @param info the information
058     * @since 7.4
059     */
060    public void addInfo(String info) {
061        if (infos == null) {
062            infos = new LinkedList<>();
063        }
064        infos.addFirst(info);
065    }
066
067    /**
068     * Gets the information added to this exception.
069     * <p>
070     * The list is returned in the reverse order than that of the calls to {@link #addInfo}, i.e., the last added
071     * information is first in the list.
072     *
073     * @return the information list
074     * @since 7.4
075     */
076    public List<String> getInfos() {
077        return infos == null ? Collections.emptyList() : infos;
078    }
079
080    /**
081     * Gets the original message passed to the constructor, without additional information added.
082     *
083     * @since 7.4
084     */
085    public String getOriginalMessage() {
086        return super.getMessage();
087    }
088
089    @Override
090    public String getMessage() {
091        String message = getOriginalMessage();
092        if (infos == null) {
093            return message;
094        } else {
095            StringBuilder sb = new StringBuilder();
096            for (String info : infos) {
097                sb.append(info);
098                sb.append(", ");
099            }
100            sb.append(message);
101            return sb.toString();
102        }
103    }
104
105}