#ifndef ExceptionState_h
#define ExceptionState_h
#include "bindings/v8/ScopedPersistent.h"
#include "bindings/v8/V8ThrowException.h"
#include "wtf/Noncopyable.h"
#include "wtf/text/WTFString.h"
#include <v8.h>
namespace WebCore {
typedef int ExceptionCode;
class ExceptionState {
WTF_MAKE_NONCOPYABLE(ExceptionState);
public:
enum Context {
ConstructionContext,
ExecutionContext,
DeletionContext,
GetterContext,
SetterContext,
EnumerationContext,
QueryContext,
IndexedGetterContext,
IndexedSetterContext,
IndexedDeletionContext,
UnknownContext,
};
ExceptionState(Context context, const char* propertyName, const char* interfaceName, const v8::Handle<v8::Object>& creationContext, v8::Isolate* isolate)
: m_code(0)
, m_context(context)
, m_propertyName(propertyName)
, m_interfaceName(interfaceName)
, m_creationContext(creationContext)
, m_isolate(isolate) { }
ExceptionState(Context context, const char* interfaceName, const v8::Handle<v8::Object>& creationContext, v8::Isolate* isolate)
: m_code(0)
, m_context(context)
, m_propertyName(0)
, m_interfaceName(interfaceName)
, m_creationContext(creationContext)
, m_isolate(isolate) { ASSERT(m_context == ConstructionContext || m_context == EnumerationContext || m_context == IndexedSetterContext || m_context == IndexedGetterContext || m_context == IndexedDeletionContext); }
virtual void throwDOMException(const ExceptionCode&, const String& message);
virtual void throwTypeError(const String& message);
virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String());
bool hadException() const { return !m_exception.isEmpty() || m_code; }
void clearException();
ExceptionCode code() const { return m_code; }
const String& message() const { return m_message; }
bool throwIfNeeded()
{
if (!hadException())
return false;
throwException();
return true;
}
Context context() const { return m_context; }
const char* propertyName() const { return m_propertyName; }
const char* interfaceName() const { return m_interfaceName; }
void rethrowV8Exception(v8::Handle<v8::Value> value)
{
setException(value);
}
protected:
ExceptionCode m_code;
Context m_context;
String m_message;
const char* m_propertyName;
const char* m_interfaceName;
private:
void setException(v8::Handle<v8::Value>);
void throwException();
String addExceptionContext(const String&) const;
ScopedPersistent<v8::Value> m_exception;
v8::Handle<v8::Object> m_creationContext;
v8::Isolate* m_isolate;
};
class NonThrowableExceptionState FINAL : public ExceptionState {
public:
NonThrowableExceptionState(): ExceptionState(ExceptionState::UnknownContext, 0, 0, v8::Handle<v8::Object>(), v8::Isolate::GetCurrent()) { }
virtual void throwDOMException(const ExceptionCode&, const String& message) OVERRIDE;
virtual void throwTypeError(const String& message = String()) OVERRIDE;
virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE;
};
class TrackExceptionState FINAL : public ExceptionState {
public:
TrackExceptionState(): ExceptionState(ExceptionState::UnknownContext, 0, 0, v8::Handle<v8::Object>(), v8::Isolate::GetCurrent()) { }
virtual void throwDOMException(const ExceptionCode&, const String& message) OVERRIDE;
virtual void throwTypeError(const String& message = String()) OVERRIDE;
virtual void throwSecurityError(const String& sanitizedMessage, const String& unsanitizedMessage = String()) OVERRIDE;
};
}
#endif