1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 module thrift.base; 20 21 /** 22 * Common base class for all Thrift exceptions. 23 */ 24 class TException : Exception { 25 /// 26 this(string msg = "", string file = __FILE__, size_t line = __LINE__, 27 Throwable next = null) 28 { 29 super(msg, file, line, next); 30 } 31 } 32 33 /** 34 * An operation failed because one or more sub-tasks failed. 35 */ 36 class TCompoundOperationException : TException { 37 /// 38 this(string msg, Exception[] exceptions, string file = __FILE__, 39 size_t line = __LINE__, Throwable next = null) 40 { 41 super(msg, file, line, next); 42 this.exceptions = exceptions; 43 } 44 45 /// The exceptions thrown by the children of the operation. If applicable, 46 /// the list is ordered in the same way the exceptions occurred. 47 Exception[] exceptions; 48 } 49 50 /// The Thrift version string, used for informative purposes. 51 // Note: This is currently hardcoded, but will likely be filled in by the build 52 // system in future versions. 53 enum VERSION = "0.16.0"; 54 55 /** 56 * Functions used for logging inside Thrift. 57 * 58 * By default, the formatted messages are written to stdout/stderr, but this 59 * behavior can be overwritten by providing custom g_{Info, Error}LogSink 60 * handlers. 61 * 62 * Examples: 63 * --- 64 * logInfo("An informative message."); 65 * logError("Some error occurred: %s", e); 66 * --- 67 */ 68 alias logFormatted!g_infoLogSink logInfo; 69 alias logFormatted!g_errorLogSink logError; /// Ditto 70 71 /** 72 * Error and info log message sinks. 73 * 74 * These delegates are called with the log message passed as const(char)[] 75 * argument, and can be overwritten to hook the Thrift libraries up with a 76 * custom logging system. By default, they forward all output to stdout/stderr. 77 */ 78 __gshared void delegate(const(char)[]) g_infoLogSink; 79 __gshared void delegate(const(char)[]) g_errorLogSink; /// Ditto 80 81 shared static this() { 82 import std.stdio; 83 84 g_infoLogSink = (const(char)[] text) { 85 stdout.writeln(text); 86 }; 87 88 g_errorLogSink = (const(char)[] text) { 89 stderr.writeln(text); 90 }; 91 } 92 93 // This should be private, if it could still be used through the aliases then. 94 template logFormatted(alias target) { 95 void logFormatted(string file = __FILE__, int line = __LINE__, 96 T...)(string fmt, T args) if ( 97 __traits(compiles, { target(""); }) 98 ) { 99 import std.format, std.stdio; 100 if (target !is null) { 101 scope(exit) g_formatBuffer.clear(); 102 103 // Phobos @@BUG@@: If the empty string put() is removed, Appender.data 104 // stays empty. 105 g_formatBuffer.put(""); 106 107 formattedWrite(g_formatBuffer, "%s:%s: ", file, line); 108 109 static if (T.length == 0) { 110 g_formatBuffer.put(fmt); 111 } else { 112 formattedWrite(g_formatBuffer, fmt, args); 113 } 114 target(g_formatBuffer.data); 115 } 116 } 117 } 118 119 private { 120 // Use a global, but thread-local buffer for constructing log messages. 121 import std.array : Appender; 122 Appender!(char[]) g_formatBuffer; 123 }