001/* 002 * Configurate 003 * Copyright (C) zml and Configurate contributors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * 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.spongepowered.configurate; 018 019import org.checkerframework.checker.nullness.qual.Nullable; 020 021import java.io.IOException; 022import java.util.function.Supplier; 023 024/** 025 * Any sort of error thrown within Configurate. 026 * 027 * <p>Configurate's errors are designed to provide a view of as 028 * many errors as possible within one configuration tree, through the 029 * {@link Throwable#getSuppressed() suppressed exceptions}</p> 030 * 031 * @since 4.0.0 032 */ 033public class ConfigurateException extends IOException { 034 035 private static final long serialVersionUID = 1635526451813128733L; 036 037 private @Nullable Supplier<NodePath> path; 038 039 /** 040 * Given an unknown {@link IOException}, return it as a Configurate type. 041 * 042 * <p>If the input {@code ex} is already a {@link ConfigurateException}, 043 * this method returns the input value.</p> 044 * 045 * @param source node where the source exception was thrown 046 * @param ex the source exception 047 * @return an exception, either casted or wrapped 048 * @since 4.0.0 049 */ 050 public static ConfigurateException wrap(final ConfigurationNode source, final IOException ex) { 051 if (ex instanceof ConfigurateException) { 052 return (ConfigurateException) ex; 053 } else { 054 return new ConfigurateException(source, ex); 055 } 056 } 057 058 /** 059 * Create a new unknown exception. 060 * 061 * @since 4.0.0 062 */ 063 public ConfigurateException() { 064 } 065 066 /** 067 * Create a new exception at unknown path with provided 068 * informational message. 069 * 070 * @param message informational message 071 * @since 4.0.0 072 */ 073 public ConfigurateException(final String message) { 074 super(message); 075 } 076 077 /** 078 * Create a new exception with a cause and unknown message. 079 * 080 * @param cause the cause of this exception 081 * @since 4.0.0 082 */ 083 public ConfigurateException(final Throwable cause) { 084 super(cause); 085 } 086 087 /** 088 * Create a new exception with informational message and cause. 089 * 090 * @param message the informational message 091 * @param cause the cause of the exception 092 * @since 4.0.0 093 */ 094 public ConfigurateException(final @Nullable String message, final @Nullable Throwable cause) { 095 super(message, cause); 096 } 097 098 /** 099 * Create a new exception pre-initialized with path and message. 100 * 101 * @param pos node where the error occurred 102 * @param message message describing the error 103 * @since 4.0.0 104 */ 105 public ConfigurateException(final ConfigurationNode pos, final String message) { 106 super(message); 107 this.path = pos::path; 108 } 109 110 /** 111 * Create a new exception pre-initialized with path and cause. 112 * 113 * @param pos node where the error occurred 114 * @param cause direct cause of this exception 115 * @since 4.0.0 116 */ 117 public ConfigurateException(final ConfigurationNode pos, final Throwable cause) { 118 super(cause); 119 this.path = pos::path; 120 } 121 122 /** 123 * Create a new exception pre-initialized with path, message, and cause. 124 * 125 * @param pos node where the error occurred 126 * @param message message describing the error 127 * @param cause direct cause of this exception 128 * @since 4.0.0 129 */ 130 public ConfigurateException(final ConfigurationNode pos, final @Nullable String message, final @Nullable Throwable cause) { 131 super(message, cause); 132 this.path = pos::path; 133 } 134 135 /** 136 * Create a new exception pre-initialized with path, message, and cause. 137 * 138 * @param path path to the node where the error occurred 139 * @param message message describing the error 140 * @param cause direct cause of this exception 141 * @since 4.0.0 142 */ 143 public ConfigurateException(final NodePath path, final @Nullable String message, final @Nullable Throwable cause) { 144 super(message, cause); 145 this.path = () -> path; 146 } 147 148 /** 149 * Get the path associated with this failure. 150 * 151 * @return the path 152 * @since 4.0.0 153 */ 154 public NodePath path() { 155 final @Nullable Supplier<NodePath> path = this.path; 156 return path == null ? NodePath.path() : path.get(); 157 } 158 159 /** 160 * Initialize path if none has been set. 161 * 162 * @param path new path 163 * @since 4.0.0 164 */ 165 public void initPath(final Supplier<NodePath> path) { 166 if (this.path == null) { 167 this.path = path; 168 } 169 } 170 171 /** 172 * Get the exception's message without any extra formatting. 173 * 174 * @return the raw message 175 * @since 4.0.0 176 */ 177 public @Nullable String rawMessage() { 178 return super.getMessage(); 179 } 180 181 /** 182 * Get a description of the location of this error, with path included. 183 * 184 * @return message 185 * @since 4.0.0 186 */ 187 @Override 188 public @Nullable String getMessage() { 189 return this.path().toString() + ": " + super.getMessage(); 190 } 191 192}