001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.reef.common; 020 021import org.apache.reef.util.Optional; 022 023import java.io.PrintWriter; 024import java.io.StringWriter; 025 026/** 027 * Common data and functionality for all error messages in REEF. 028 */ 029public abstract class AbstractFailure implements Failure { 030 031 /** 032 * Identifier of the entity that produced the error. Cannot be null. 033 */ 034 private final String id; 035 036 /** 037 * One-line error message. For wrapped exceptions, this equals 038 * to the Exception.getMessage() result. Cannot be null. 039 */ 040 private final String message; 041 042 /** 043 * Optional error description (long). 044 * For exceptions it is by default populates with the stack trace. 045 */ 046 private final Optional<String> description; 047 048 /** 049 * Optional Java exception that caused the error. 050 */ 051 private final Optional<Throwable> cause; 052 053 /** 054 * Optional byte array that contains serialized version of the exception. 055 */ 056 private final Optional<byte[]> data; 057 058 /** 059 * @param id Identifier of the entity that produced the error. Cannot be null. 060 * @param message One-line error message. Cannot be null. 061 * @param description Long error description. Can be null. 062 * @param cause Java Exception that caused the error. Can be null. 063 * @param data byte array that contains serialized version of the error. Can be null. 064 */ 065 protected AbstractFailure(final String id, 066 final String message, 067 final Optional<String> description, 068 final Optional<Throwable> cause, 069 final Optional<byte[]> data) { 070 this.id = id; 071 this.message = message; 072 this.description = description; 073 this.cause = cause; 074 this.data = data; 075 } 076 077 078 /** 079 * Helper function: produce the string that contains the given exception's stack trace. 080 * Returns null if the argument is null. 081 * 082 * @param cause Java Exception or null. 083 * @return A string that contains the exception stack trace, or null. 084 */ 085 protected static String getStackTrace(final Throwable cause) { 086 if (cause == null) { 087 return null; 088 } else { 089 final StringWriter writer = new StringWriter(); 090 cause.printStackTrace(new PrintWriter(writer)); 091 return writer.toString(); 092 } 093 } 094 095 /** 096 * @return Identifier of the entity that produced the error. Never null. 097 */ 098 @Override 099 public String getId() { 100 return this.id; 101 } 102 103 /** 104 * @return One-line error message. Never null. 105 */ 106 @Override 107 public String getMessage() { 108 return this.message; 109 } 110 111 /** 112 * @return Optional long error description. For Java Exceptions, can contain stack trace. 113 */ 114 @Override 115 public Optional<String> getDescription() { 116 return this.description; 117 } 118 119 @Override 120 public Optional<Throwable> getReason() { 121 return this.cause; 122 } 123 124 /** 125 * @return Optional serialized version of the error message. 126 */ 127 @Override 128 public Optional<byte[]> getData() { 129 return this.data; 130 } 131 132 /** 133 * Return the original Java Exception, or generate a new one if it does not exists. 134 * ALWAYS returns an exception. 135 * FIXME: Replace RuntimeException with a better class. 136 * 137 * @return A java exception. Never null. 138 */ 139 @Override 140 public Throwable asError() { 141 return this.cause.isPresent() ? this.cause.get() : new RuntimeException(this.toString()); 142 } 143 144 /** 145 * @return Human-readable string representation of an error message. 146 */ 147 @Override 148 public String toString() { 149 return this.getClass().getName() + " id=" + this.getId() + " failed: " + this.getMessage(); 150 } 151}