/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef LIBHDFS_EXCEPTION_H #define LIBHDFS_EXCEPTION_H /** * Exception handling routines for libhdfs. * * The convention we follow here is to clear pending exceptions as soon as they * are raised. Never assume that the caller of your function will clean up * after you-- do it yourself. Unhandled exceptions can lead to memory leaks * and other undefined behavior. * * If you encounter an exception, return a local reference to it. The caller is * responsible for freeing the local reference, by calling a function like * printExceptionAndFree. (You can also free exceptions directly by calling * DeleteLocalRef. However, that would not produce an error message, so it's * usually not what you want.) * * The root cause and stack trace exception strings retrieved from the last * exception that happened on a thread are stored in the corresponding * thread local state and are accessed by hdfsGetLastExceptionRootCause and * hdfsGetLastExceptionStackTrace respectively. */ #include "platform.h" #include #include #include #include #include #include /** * Exception noprint flags * * Theses flags determine which exceptions should NOT be printed to stderr by * the exception printing routines. For example, if you expect to see * FileNotFound, you might use NOPRINT_EXC_FILE_NOT_FOUND, to avoid filling the * logs with messages about routine events. * * On the other hand, if you don't expect any failures, you might pass * PRINT_EXC_ALL. * * You can OR these flags together to avoid printing multiple classes of * exceptions. */ #define PRINT_EXC_ALL 0x00 #define NOPRINT_EXC_FILE_NOT_FOUND 0x01 #define NOPRINT_EXC_ACCESS_CONTROL 0x02 #define NOPRINT_EXC_UNRESOLVED_LINK 0x04 #define NOPRINT_EXC_PARENT_NOT_DIRECTORY 0x08 #define NOPRINT_EXC_ILLEGAL_ARGUMENT 0x10 #ifdef WIN32 #ifdef LIBHDFS_DLL_EXPORT #define LIBHDFS_EXTERNAL __declspec(dllexport) #elif LIBHDFS_DLL_IMPORT #define LIBHDFS_EXTERNAL __declspec(dllimport) #else #define LIBHDFS_EXTERNAL #endif #else #ifdef LIBHDFS_DLL_EXPORT #define LIBHDFS_EXTERNAL __attribute__((visibility("default"))) #elif LIBHDFS_DLL_IMPORT #define LIBHDFS_EXTERNAL __attribute__((visibility("default"))) #else #define LIBHDFS_EXTERNAL #endif #endif /** * Get information about an exception. * * @param excName The Exception name. * This is a Java class name in JNI format. * @param noPrintFlags Flags which determine which exceptions we should NOT * print. * @param excErrno (out param) The POSIX error number associated with the * exception. * @param shouldPrint (out param) Nonzero if we should print this exception, * based on the noPrintFlags and its name. */ LIBHDFS_EXTERNAL void getExceptionInfo(const char *excName, int noPrintFlags, int *excErrno, int *shouldPrint); /** * Store the information about an exception in the thread-local state and print * it and free the jthrowable object. * * @param env The JNI environment * @param exc The exception to print and free * @param noPrintFlags Flags which determine which exceptions we should NOT * print. * @param fmt Printf-style format list * @param ap Printf-style varargs * * @return The POSIX error number associated with the exception * object. */ LIBHDFS_EXTERNAL int printExceptionAndFreeV(JNIEnv *env, jthrowable exc, int noPrintFlags, const char *fmt, va_list ap); /** * Store the information about an exception in the thread-local state and print * it and free the jthrowable object. * * @param env The JNI environment * @param exc The exception to print and free * @param noPrintFlags Flags which determine which exceptions we should NOT * print. * @param fmt Printf-style format list * @param ... Printf-style varargs * * @return The POSIX error number associated with the exception * object. */ LIBHDFS_EXTERNAL int printExceptionAndFree(JNIEnv *env, jthrowable exc, int noPrintFlags, const char *fmt, ...) TYPE_CHECKED_PRINTF_FORMAT(4, 5); /** * Store the information about the pending exception in the thread-local state * and print it and free the jthrowable object. * * @param env The JNI environment * @param noPrintFlags Flags which determine which exceptions we should NOT * print. * @param fmt Printf-style format list * @param ... Printf-style varargs * * @return The POSIX error number associated with the exception * object. */ LIBHDFS_EXTERNAL int printPendingExceptionAndFree(JNIEnv *env, int noPrintFlags, const char *fmt, ...) TYPE_CHECKED_PRINTF_FORMAT(3, 4); /** * Get a local reference to the pending exception and clear it. * * Once it is cleared, the exception will no longer be pending. The caller will * have to decide what to do with the exception object. * * @param env The JNI environment * * @return The exception, or NULL if there was no exception */ LIBHDFS_EXTERNAL jthrowable getPendingExceptionAndClear(JNIEnv *env); /** * Create a new runtime error. * * This creates (but does not throw) a new RuntimeError. * * @param env The JNI environment * @param fmt Printf-style format list * @param ... Printf-style varargs * * @return A local reference to a RuntimeError */ LIBHDFS_EXTERNAL jthrowable newRuntimeError(JNIEnv *env, const char *fmt, ...) TYPE_CHECKED_PRINTF_FORMAT(2, 3); #undef TYPE_CHECKED_PRINTF_FORMAT #undef LIBHDFS_EXTERNAL #endif