001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.marshall.serializer; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020 021import java.lang.reflect.*; 022import java.util.*; 023 024import org.apache.juneau.marshall.*; 025import org.apache.juneau.marshall.marshaller.*; 026 027/** 028 * General exception thrown whenever an error occurs during serialization. 029 * 030 * <h5 class='section'>See Also:</h5><ul> 031 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SerializersAndParsers">Serializers and Parsers</a> 032 033 * </ul> 034 * 035 * @serial exclude 036 */ 037@SuppressWarnings({ 038 "java:S110" // Deep inheritance inherent to the exception hierarchy 039}) 040public class SerializeException extends BasicRuntimeException { 041 042 private static final long serialVersionUID = 1L; 043 044 /** 045 * Creator method. 046 * 047 * <p> 048 * If the throwable is already a {@link SerializeException}, we simply return that exception as-is. 049 * If the throwable is an {@link InvocationTargetException}, we unwrap the thrown exception. 050 * Otherwise we create a new {@link SerializeException}. 051 * 052 * @param e The exception being wrapped or unwrapped. 053 * Must not be <jk>null</jk>. 054 * @return The specified throwable wrapped or unwrapped as a {@link SerializeException} (may be the same instance if it already was one). 055 */ 056 public static SerializeException create(Throwable e) { 057 if (e instanceof InvocationTargetException e2) 058 e = e2.getCause(); 059 if (e instanceof SerializeException e2) 060 return e2; 061 return new SerializeException(e); 062 } 063 064 private static String getMessage(SerializerSession session, String msg, Object...args) { 065 msg = f(msg, args); 066 if (nn(session)) { 067 Map<String,Object> m = session.getLastLocation(); 068 if (nn(m) && ! m.isEmpty()) 069 msg = "Serialize exception occurred at " + Json5.of(m) + ". " + msg; 070 } 071 return msg; 072 } 073 074 /** 075 * Constructor. 076 * 077 * @param session The serializer session to extract information from. 078 * Can be <jk>null</jk> (the message is not augmented with location info). 079 * @param causedBy The inner exception. 080 * Must not be <jk>null</jk>. 081 */ 082 public SerializeException(SerializerSession session, Exception causedBy) { 083 super(causedBy, getMessage(session, causedBy.getMessage())); 084 } 085 086 /** 087 * Constructor. 088 * 089 * @param session The serializer session to extract information from. 090 * Can be <jk>null</jk> (the message is not augmented with location info). 091 * @param message The exception message containing {@link String#format(String, Object...) String.format}-style (<c>%s</c>) arguments. 092 * @param args Optional {@link String#format(String, Object...) String.format}-style arguments. 093 */ 094 public SerializeException(SerializerSession session, String message, Object...args) { 095 super(getMessage(session, message, args)); 096 } 097 098 /** 099 * Constructor. 100 * 101 * @param message The exception message containing {@link String#format(String, Object...) String.format}-style (<c>%s</c>) arguments. 102 * @param args Optional {@link String#format(String, Object...) String.format}-style arguments. 103 */ 104 public SerializeException(String message, Object...args) { 105 super(getMessage(null, message, args)); 106 } 107 108 /** 109 * Constructor. 110 * 111 * @param causedBy The inner exception. 112 * Must not be <jk>null</jk>. 113 */ 114 public SerializeException(Throwable causedBy) { 115 super(causedBy, getMessage(null, causedBy.getMessage())); 116 } 117 118 /** 119 * Returns the highest-level <c>SerializeException</c> in the stack trace. 120 * Useful for JUnit testing of error conditions. 121 * 122 * @return The root serialize exception, or this exception if there isn't one. 123 */ 124 public SerializeException getRootCause() { 125 SerializeException t = this; 126 while (! (t.getCause() == null || ! (t.getCause() instanceof SerializeException t2))) 127 t = t2; 128 return t; 129 } 130 131 /** 132 * Sets the inner cause for this exception. 133 * 134 * @param cause The inner cause. 135 * @return This object. 136 */ 137 @Override /* Overridden from Throwable */ 138 public synchronized SerializeException initCause(Throwable cause) { 139 super.initCause(cause); 140 return this; 141 } 142 143 @Override /* Overridden from BasicRuntimeException */ 144 public SerializeException setMessage(String message, Object...args) { 145 super.setMessage(message, args); 146 return this; 147 } 148}