Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have been trying to find a way to enforce unique error messages in our application. That is, I want to know exactly which line of code produced the error, so when users contact support we know the source of the error from the message logged.
I found this question which gave me a mechanism (using guids to enforce uniqueness), but one question remains: How do I prevent copy/paste duplication? - specifically, a developer copying the logging line itself:
Log(<guid>, errorMessage);
In this case the guid would be duplicated and no longer useful for identifying the unique line which generated the error.
The one idea I have had which would actually work is writing a tool to be run by our build server which would parse the code for error message guids, keep a list, and fail the build on a duplicate. I'm wondering if there is a cleaner solution.
Other things I've considered:
There are various ideas using some sort of central listing of error messages, but I have not found one which addresses the copy/paste issue.
There are also a number of schemes which would require keeping a manual list in some way. I don't want to pursue something like this as it creates the possibility of discrepancies between the list & production code.
I've also seen suggestions to use the stack trace, but I'm a bit hesitant to do that for security & performance reasons.
I don't know if this is really what you're looking for, but you can include the file, method, line number (and other things) in your log message without needing a unique number that you would later search the source code for if you make use of the System.Diagnostics.StackTrace class. This way, even if there's a copy/paste violation, you still know exactly where the call to Log came from.
Here's a simplified example that returns the file name, method signature, and line number of a stack trace item. Note that this code finds the stack trace item for a call to the "Log" method and returns the next one. That will be more clear shortly:
using System.Diagnostics; // Needed for the StackTrace class
private static string GetStackTraceInfo()
{
var stackTrace = new StackTrace(true).GetFrames();
// Find the item just after the call to teh 'Log' method:
var item = stackTrace?
.SkipWhile(st => !st.GetMethod().Name.Equals("Log"))
.Skip(1)
.FirstOrDefault();
return item == null
? string.Empty
: string.Format("{0} => {1}, line #{2}", Path.GetFileName(item.GetFileName()),
item.GetMethod(), item.GetFileLineNumber());
}
Here's the Log method that enforces the stack trace info added to a log (and this is the method name that we were searching for in the code above):
private static void Log(int id, string message)
{
Console.WriteLine($"Error #{id}: {message} ({GetStackTraceInfo()})");
}
And an example usage:
private static void Main()
{
DoSomething();
DoSomethingElse();
GetKeyFromUser("\nDone! Press any key to exit...");
}
private static void DoSomething()
{
Log(1000, "I copied/pasted this error message from somewhere!");
}
private static void DoSomethingElse()
{
Log(1000, "I copied/pasted this error message from somewhere!");
}
Output
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Okay, so I am very new to Vulkan API, as seen in my last question. I am very confused about why vkCreateSwapchainKHR results in an access denied.
I have tried re-typing the code. I have tried Minimal Viable code. I have also tried initializing the swap chain at different times, but they all seem to not work.
The variables like _sur_capab are surface capabilities were got earlier than this. And, _logicalDevice was just an instance of VkDevice.
VkSwapchainCreateInfoKHR cri = { };
cri.clipped = VK_TRUE;
cri.oldSwapchain = VK_NULL_HANDLE;
cri.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
cri.flags = VkSwapchainCreateFlagBitsKHR::VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR;
cri.imageArrayLayers = 1;
cri.imageColorSpace = VkColorSpaceKHR::VK_COLORSPACE_SRGB_NONLINEAR_KHR;
cri.imageExtent = _sur_capab.maxImageExtent;
cri.imageFormat = VkFormat::VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
cri.imageSharingMode = VkSharingMode::VK_SHARING_MODE_MAX_ENUM;
cri.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
cri.minImageCount = _sur_capab.minImageCount;
cri.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
cri.preTransform = _sur_capab.currentTransform;
vkCreateSwapchainKHR(
_logicalDevice,
&cri,
nullptr,
&_swapChain);
One advice up front: Always run your applications with the validation layers enabled, they should hint you at the potential problems in your code.
Without knowing the remaining relevant code parts, I can see several potential problems with your code above:
First one is the fact that you're setting invalid values for flags and imageSharingMode. The _MAX_ENUM_ values are not be used for initialization, so you need to pass proper values there. Usually it's 0 for the flags and e.g. VK_SHARING_MODE_EXCLUSIVE for the imageSharingMode. Check the specs to see what values are valid for the members of your VkSwapchainCreateInfoKHR structure.
Next up you need to check if the imageFormat you request is actually supported on your device via vkGetPhysicalDeviceSurfaceFormatsKHR. VK_FORMAT_ASTC_5x4_UNORM_BLOCK is a pretty specific format and I can imagine that only a very few, if any at all, implementations support this as a surface format.
It also looks like you're not setting the presentMode at all, making it 0 due to initialization, which equals to VK_PRESENT_MODE_IMMEDIATE_KHR. This mode may not be supported on your target implementation, just like the image format. You need to either select a present mode that's available everywhere, or properly select one that's supported via vkGetPhysicalDeviceSurfacePresentModesKHR.
When It is possible to define a custom ErrorCollector class for handling google::protobuf parsing errors
struct ErrorCollector : ::google::protobuf::io::ErrorCollector
{
void AddError(int line, int column, const std::string& message) override
{
// log error
}
void AddWarning(int line, int column, const std::string& message) override
{
// log warning
}
};
When parsing from a text file, you can use the protobuf TextFormat class and register your custom ErrorCollector
::google::protobuf::io::IstreamInputStream input_stream(&file);
::google::protobuf::TextFormat::Parser parser;
ErrorCollector error_collector;
parser.RecordErrorsTo(&error_collector);
if (parser.Parse(&input_stream, &msg))
{
// handle msg
}
For parsing wire format, I currently use Message::ParseFromArray
if (msg.ParseFromArray(data, data_len))
{
// handle msg
}
This doesn't allow me to specify a custom ErrorCollector though.
I've searched through the source code, but as of yet have been unable to find if this is possible.
Is it possible to use an ErrorCollector when parsing wire format?
Is there another way to intercept parse errors and make them available to client code?
There are essentially two ways that parsing the wire format could fail:
The bytes are not a valid protobuf (e.g. they are corrupted, or in a totally different format).
A required field is missing.
For case 1, protobuf does not give you any more information than "it's invalid". This is partly for code simplicity (and speed), but it is also partly because any attempt to provide more information usually turns out more misleading than helpful. Detailed error reporting is useful for text format because text is often written by humans, but machines make very different kinds of errors. In some languages, protobuf actually reports specific errors like "end-group tag does not match start-group tag". In the vast majority of cases, this error really just means "the bytes are corrupted", but inevitably people think the error is trying to tell them something deeper which they do not understand. They then post questions to stack overflow like "How do I make sure my start-group and end-group tags match?" when they really should be comparing bytes between their source and destination to narrow down where they got corrupted. Even reporting the byte position where the parse error occurred is not very useful: protobuf is a dense encoding, which means that many random corrupt byte sequences will parse successfully, which means the parser may only notice a problem somewhere later down the line rather than at the point where things actually went wrong.
The one case that clearly is useful to distinguish is case 2 (missing required fields) -- at least, if you use required fields (I personally recommend avoiding them). There are a couple options here:
Normally, required field checks write errors to the console (on stderr). You can intercept these and record them your own way using SetLogHandler, but this doesn't give you structured information, only text messages.
To check required fields more programmatically, you can separate required field checking from parsing. Use MessageLite::ParsePartialFromArray() or one of the other Partial parsing methods to parse a message while ignoring the absence of required fields. You can then use the MessageLite::IsInitialized() to check if all required fields are set. If it returns false, use Message::FindInitializationErrors() to get a list of paths of all required fields that are missing.
XPages application fails with following stack trace:
com.ibm.jscript.InterpretException: Script interpreter error, line=30, col=43: 'component' is null
at com.ibm.jscript.ASTTree.ASTMember.interpret(ASTMember.java:153)
at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:88)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85)
at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100)
at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109)
at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85)
at com.ibm.jscript.ASTTree.ASTProgram.interpret(ASTProgram.java:119)
at com.ibm.jscript.ASTTree.ASTProgram.interpretEx(ASTProgram.java:139)
From this I know, that there is problem with variable "component" nested inside hierarchy of blocks:
if -> try -> { -> if -> { -> if -> { -> method call with invalid argument.
I don't know what to look for exactly, search for "component" yields too many results.
What regex should I use to find the right spot based on code hierarchy?
In this case I see a good chance that you have not put all your SSJS code into try/catch blocks. The bad news: searching the cause of this error is extremely cumbersome as close to all SSJS blocks may be the root cause of this error.
For that reason I placed my own rule (and ignore it every now and then) to put EVERY SSJS block into a try/catch like this:
try {
// ... do fancy stuff here
} catch (e) {
print(e.toString());
}
The toString() call is used for some special cases where the error object appears to no automatically convert into an object that can be handled by the print method.
If it is the case, you have not put all SSJS blocks into a try/catch, this is exactly the right time to do so and keep that coding pattern for the future. It really helps every now and then ;-)
Instead of printStackTrace and toString() , you could just say print(e), which will output only the error message(should be the same as e.message). The error object if passed to a java routine, you could get the error line.
variable "component" nested inside hierarchy of blocks ==> We have made this working without issues.
Here's what I am trying to figure out, their docs don't explain this well enough, at least to me..
Senario:
I have 5 proto files that I generate with protoc for C++. My application needs to receive a message and then be able to iterate through all the fields while accessing their values and names.
What I would like to do is parse a message into the DynamicMessage class and then do the iteration through the fields. This way I don't have to know exactly what message it is and I can handle them all in a single generic way.
I know it's possible to handle the messages by parsing them to their specific type then treating them as their Message base class but for my application that is not desirable.
It looks like what I want to do should be possible via the "--descriptor_set_out" and dynamic message class.
What I've Tried (And Failed With):
I moved the descriptor.proto into the folder with my protos and included it along side my others in the compilation step. I also set the--descriptor_set_out flag to print to a file "my_descriptors.pb.ds"
I have no idea where to proceed from there.
Here's what i've referenced, although there isn't much...
Sorry for the long post, and somewhat vague topic naming schema.
Also, incase it wasn't clear, I assume the messages aren't "Unknown." I assume there will still be the requirement of including the respective headers for each proto so my code knows about the 'unknown' message its handling.
The most common way is to use message composition. Something like:
message Foo {...}
message Bar {...}
message GenericMessage {
enum Type {FOO = 1, BAR = 2};
optional Foo foo = 1;
optional Bar bar = 2;
}
If you make sure that exactly one of either Foo or Bar is present in each GenericMessage, you get the desired behaviour. You read one GenericMessage and then process it as one of several specific messages.
Think about refactoring the protocol. If all you need to do is iterate over the fields, maybe you'd be better off with something like a simple key-value map:
message ValueMessage {
required string key = 1;
optional int IntValue = 2;
optional string StringValue = 3;
optional bool BoolValue = 4;
...
}
message GenericMessage{
repeated ValueMessage = 1;
}
Or maybe you can refactor you protocol some other way.
Warning: my answer is not completely correct I am having some compilation errors regarding conflicts, i will edit when I fix it :). but this is a starting point
It might have been a long time since this question was posted, but I faced something similar this days now working with Protocol Buffers.
First of all the reference is wrong the option on the command that must be added is:
--descriptor_set_out=<Directory>
where Directory is where your compiled version of the descriptor.proto (or .proto compiled that describes your file) is located.
after this you will have to add the reference to the Descriptor.proto file in your autodescriving .proto file.
message MyMessage
{
required google.protobuf.FileDescriptorSet proto_files = 1;
...
}
I have a Win32 C++ program that validates user input and updates the UI with status information and options. Currently it is written like this:
void ShowError() {
SetIcon(kError);
SetMessageString("There was an error");
HideButton(kButton1);
HideButton(kButton2);
ShowButton(kButton3);
}
void ShowSuccess() {
SetIcon(kError);
std::String statusText (GetStatusText());
SetMessageString(statusText);
HideButton(kButton1);
HideButton(kButton2);
ShowButton(kButton3);
}
// plus several more methods to update the UI using similar mechanisms
I do not likes this because it duplicates code and causes me to update several methods if something changes in the UI.
I am wondering if there is a design pattern or best practice to remove the duplication and make the functionality easier to understand and update.
I could consolidate the code inside a config function and pass in flags to enable/disable UI items, but I am not convinced this is the best approach.
Any suggestions and ideas?
I would recommend Observer Pattern and State Pattern, when an validation happens to be successful or unsuccessful, attached buttons can change their state according to information provided in "notify" method. Please refer to GoF's book for further details, or just google them. Hope it helps.