// // BlueprintErrors: Better error handling for blueprint errors. // #pragma once #include "Containers/Array.h" #include "CoreMinimal.h" #include "HAL/Platform.h" #include "Misc/OutputDeviceError.h" #include "UObject/NameTypes.h" #include "UObject/ObjectMacros.h" #include "UObject/UObjectGlobals.h" #include "BlueprintErrors.generated.h" /* * enum class ElxLogVerbosity, below, contains all the same error severity levels * as ELogVerbosity, but in a form that the blueprint editor can manipulate. * * We deliberately moved 'Fatal' to the end of the list, and made 'Error' option 0. * We did that because we want the editor to default to 'Error' in most cases. * Unfortunately, that means the numeric values of the two enums don't match up, * so we will need a conversion function. * */ /** Log Verbosity: The importance of an error message, which affects which logs the error * message gets written to, and how that message gets filtered. * */ UENUM(BlueprintType) enum class ElxLogVerbosity : uint8 { /* Prints an error to the console and log file. The editor collects and reports errors. */ Error, /* Prints a warning to the console and log file. The editor collects and report warnings. */ Warning, /* Prints a message to the console and log file. */ Display, /* Prints a message to the log file, however, it does not print to the console. */ Log, /* Prints a message to a log file only if Verbose logging is enabled for the given category. This is usually used for detailed logging. */ Verbose, /* Prints a message to a log file. If VeryVerbose logging is enabled, then this is used for detailed logging that would otherwise spam output. */ VeryVerbose, /* Danger! Prints a fatal error to the console and log file, then crashes (this crashes the editor too). */ Fatal, }; /** Display Duration: How long to display an error message in the game's viewport. * */ UENUM(BlueprintType) enum class ElxErrorDisplayDuration : uint8 { /* Do not display the message in the viewport */ No_Show = 0, /* Display the message in the viewport for 1 seconds */ Show_1_Seconds = 1, /* Display the message in the viewport for 2 seconds */ Show_2_Seconds = 2, /* Display the message in the viewport for 3 seconds */ Show_3_Seconds = 3, /* Display the message in the viewport for 4 seconds */ Show_4_Seconds = 4, /* Display the message in the viewport for 5 seconds */ Show_5_Seconds = 5, /* Display the message in the viewport for 10 seconds */ Show_10_Seconds = 10, /* Display the message in the viewport for 20 seconds */ Show_20_Seconds = 20, /* Display the message in the viewport for 30 seconds */ Show_30_Seconds = 30, /* Display the message in the viewport for 40 seconds */ Show_40_Seconds = 40, /* Display the message in the viewport for 50 seconds */ Show_50_Seconds = 50, /* Display the message in the viewport for 60 seconds */ Show_60_Seconds = 60, /* Display the message in the viewport for 70 seconds */ Show_70_Seconds = 70, /* Display the message in the viewport for 80 seconds */ Show_80_Seconds = 80, /* Display the message in the viewport for 90 seconds */ Show_90_Seconds = 90, /* Display the message in the viewport for 1 minutes */ Show_1_Minutes = 101, /* Display the message in the viewport for 2 minutes */ Show_2_Minutes = 102, /* Display the message in the viewport for 3 minutes */ Show_3_Minutes = 103, /* Display the message in the viewport for 4 minutes */ Show_4_Minutes = 104, /* Display the message in the viewport for 5 minutes */ Show_5_Minutes = 105, }; /* A library containing assorted useful functions for blueprint error handling. * */ UCLASS(MinimalAPI) class UlxBlueprintErrorLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() public: // The Format Error Message blueprint node macroexpands, the following // function is the core of the expansion. The actual K2Node itself is in // its own source file. // UFUNCTION(BlueprintCallable, meta=(WorldContext = "Context", BlueprintInternalUseOnly = "true")) static void FormatErrorInternal(UObject *Context, ElxLogVerbosity Verbosity, ElxErrorDisplayDuration DisplayDuration, const FString &InPattern, TArray InArgs); // Convert an ElxLogVerbosity to an ELogVerbosity::Type // static ELogVerbosity::Type ConvertElxLogVerbosity(ElxLogVerbosity Verbosity); }; /* Debug Blueprint Errors output device. * * When an error message gets written to the log, using "Format Error Message," * or any other means that writes an error message to the log, * we can optionally notify the blueprint debugger to pause execution. * This only affects errors that are generated during blueprint execution. * Errors in other threads do not pause the blueprint. * */ struct FlxDebugBlueprintErrorsOutputDevice : public FOutputDevice { public: // The constructor and destructor automatically register this output device with GLog. // // This struct doesn't store the sensitivity threshold. It relies on some blueprint // class to do that, so that the threshold can be easily edited with the blueprint // editor. This struct must be initialized with a reference to the threshold variable. // FlxDebugBlueprintErrorsOutputDevice(const ElxLogVerbosity &SensitivityRef); ~FlxDebugBlueprintErrorsOutputDevice(); // Inspect a log message. // INTEGRATION_API virtual void Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const FName& Category) override; // If the device is marked 'CanBeUsedOnMultipleThreads,' then UE_LOG will // call Serialize from the current thread, otherwise, it will call Serialize from // the logging thread. Using the logging thread would defeat the purpose of this // device, so it's imperative that we set this flag. // INTEGRATION_API virtual bool CanBeUsedOnMultipleThreads() const override { return true; } private: const ElxLogVerbosity &Sensitivity; };