blob: 57aec1818d3d61dbfa443428e8c1213105526617 [file] [log] [blame]
Jake Farrellb95b0ff2012-03-22 21:49:10 +00001/*
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 */
19module thrift.base;
20
21/**
22 * Common base class for all Thrift exceptions.
23 */
24class 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 */
36class 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,
Konrad Grochowski3b5dacb2014-11-24 10:55:31 +010046 /// the list is ordered in the same way the exceptions occurred.
Jake Farrellb95b0ff2012-03-22 21:49:10 +000047 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.
53enum VERSION = "0.9.0 dev";
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.");
Konrad Grochowski3b5dacb2014-11-24 10:55:31 +010065 * logError("Some error occurred: %s", e);
Jake Farrellb95b0ff2012-03-22 21:49:10 +000066 * ---
67 */
68alias logFormatted!g_infoLogSink logInfo;
69alias 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
81shared 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.
94template logFormatted(alias target) {
95 void logFormatted(string file = __FILE__, int line = __LINE__,
Jens Geyer83cd3e82015-05-17 19:44:01 +020096 T...)(string fmt, T args) if (
Jake Farrellb95b0ff2012-03-22 21:49:10 +000097 __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) {
Jens Geyer83cd3e82015-05-17 19:44:01 +0200110 g_formatBuffer.put(fmt);
Jake Farrellb95b0ff2012-03-22 21:49:10 +0000111 } else {
Jens Geyer83cd3e82015-05-17 19:44:01 +0200112 formattedWrite(g_formatBuffer, fmt, args);
Jake Farrellb95b0ff2012-03-22 21:49:10 +0000113 }
114 target(g_formatBuffer.data);
115 }
116 }
117}
118
119private {
120 // Use a global, but thread-local buffer for constructing log messages.
121 import std.array : Appender;
122 Appender!(char[]) g_formatBuffer;
123}