I have a function that loops through a list of servers, and then for each carries out a number of functions.
At the beginning each iteration, I need to calculate which 'step' the process is currently at (so that a progress bar can be updated correctly), but this line is causing an error -
Me.CurrentStepLoop = ((Me.CurrentServerLoop - 1) * Me.ServerSteps) + 1
All three of the referenced properties are integers, and the values are quite low (I.e CurrentServerLoop has a maximum of 6 and ServerSteps has a maximum of 20, soCurrentStepLoop can be no more that 101 from this equation.
Here is the error that I am getting -
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
Additional information: Exception has been thrown by the target of an invocation.
I find it particularly odd that I have the line in question within a Try...Catch, yet the error is not handled by my code and instead I see generic Visual Exchange error. The line is not actually highlighted, but I know it is that as if I comment it out the error does not occur
Can anybody shed some light on why this may be happening? Thanks.
Here is the snippit that I believe is causing the issue, as well as a link to the full code -
For Each CurrentServer In Me.Servers
If bw.CancellationPending = True Then
e.Cancel = True
Exit For
Else
Try
Me.CurrentStepLoop = ((Me.CurrentServerLoop - 1) * Me.ServerSteps) + 1
Catch Ex As Exception
Dim ErrorForm As New formError(Ex)
e.Cancel = True
Exit For
End Try
MappingResult = Me.DoMapDrives(CurrentServer)
If Not MappingResult Then bw.CancelAsync() : Exit For
{...Other actions here...}
CurrentServerLoop += 1
End If
Next
I have found the error and why it occurred.
In the method SetSteps() I calculate Me.StepSize, but I was doing so incorrectly. Changing this -
Me.StepSize = Me.proProgress.Maximum / Me.ServerSteps
To this solved the problem -
Me.StepSize = Me.proProgress.Maximum / Me.TotalSteps
The issue was that the Progress bar was being set passed it's maximum, which caused the error. Thanks.
Related
In the software called Roblox studio I need help making a script that whenever an error happens in game, it would print out the error again using the normal print function something like this example here:
Local error = —-whatever the error that happened was
Print(error) —- so it just simply prints it back out
Roblox provides a few different ways to keep track of when errors are thrown in your Scripts and LocalScripts.
If you want to observe errors locally in a script, and you know a specific chunk of code may throw errors, you can use pcall() as a try-catch block.
local success, result = pcall(function()
error("this is a test error message")
end)
if not success then
print("An error was thrown!")
print(result) --"this is a test error message"
end
If you want to observe errors across all of your scripts, you can attach a callback to the ScriptContext.Error signal. This signal fires any time any error is thrown. It provides information about the error, including the message, the callstack, and a reference to the script that threw the error.
Warning : ScriptContext.Error only fires in the context of the script that registers it. A Script will only observe errors thrown in server scripts, and registering in a LocalScript will only observe errors thrown on the client.
local ScriptContext = game:GetService("ScriptContext")
ScriptContext.Error:Connect( function(message, stack, context)
print("An error was thrown!")
print("Message : ", message)
print("Stack : ", stack)
print("Context :", context:GetFullName())
end)
Similarly, if you only care about the error messages themselves, you can also observe them being printed out to the Output window using the LogService.MessageOut signal. This signal fires any time anything is logged to Output. This includes messages, warnings, and errors.
local LogService = game:GetService("LogService")
LogService.MessageOut:Connect( function(message, messageType)
if messageType == Enum.MessageType.MessageError then
print("An error was thrown!")
print(message)
end
end)
Use the stderr stream from io library to print debug messages.
-- Define debug function based in print
function debug(...) io.stderr:write(table.concat({...}, '\9') .. '\n') end
-- Debug acts as a regular "print()", but it writes to stderr instead
debug('[filename.lua]', 'debug')
Use "error()" function to print errors.
if true then
error("It should not be true!")
end
If you want to catch errors from a function, use xpcall()
-- Define debug
function debug(...) io.stderr:write(table.concat({...}, '\9') .. '\n') end
xpcall(
function()
local b = {}
-- This will throw an error because you cant index nil values
print(a.b)
end,
function(err)
debug('[xpcall]', err)
end
)
xpcall() wont stop the execution in case of error, so you only need to encapsulate your code in it if you want to catch any unexpected errors at runtime.
Is it possible to throw a Lua error from a function to be handled by the script calling the function?
For example the following will throw an error at indicated comment
local function aSimpleFunction(...)
string.format(...) -- Error is indicated to be here
end
aSimpleFunction("An example function: %i",nil)
But what I would rather do is catch the error and throw out a custom error by the function caller
local function aSimpleFunction(...)
if pcall(function(...)
string.format(...)
end) == false then
-- I want to throw a custom error to whatever is making the call to this function
end
end
aSimpleFunction("An example function: %i",nil) -- Want the error to start unwinding here
The intention being that in my actual use cases my functions would be more complicated and I would like to provide more meaningful error messages
The stack level of an error can be specified when throwing a new error
error("Error Message") -- Throws at the current stack
error("Error Message",2) -- Throws to the caller
error("Error Message",3) -- Throws to the caller after that
Usually, error adds some information about the error position at the beginning of the message. The level argument specifies how to get the error position. With level 1 (the default), the error position is where the error function was called. Level 2 points the error to where the function that called error was called; and so on. Passing a level 0 avoids the addition of error position information to the message.
Using the example given in the question
local function aSimpleFunction(...)
if pcall(function(...)
string.format(...)
end) == false then
error("Function cannot format text",2)
end
end
aSimpleFunction("An example function: %i",nil) --Error appears here
Use the error function.
error("something went wrong!")
Catching an error is as simple as using pcall
My_Error()
--Error Somehow
end
local success,err = pcall(My_Error)
if not success then
error(err)
end
Undoubtedly you're asking how this works. Well pcall runs a function in a protected thread (protected-call) and returns a bool, if it ran successfully, and a value (what it returned/the error).
Also don't think this means arguments to the function are impossible, simply pass them to pcall as well:
My_Error(x)
print(x)
--Error Somehow
end
local success,err = pcall(My_Error, "hi")
if not success then
error(err)
end
For more error handling control, see http://www.lua.org/manual/5.3/manual.html#2.3 and http://wiki.roblox.com/index.php?title=Function_dump/Basic_functions#xpcall
When I'm creating a purchase order that have 10 items (or above), a run time error occurred. Below is the error message.
Category: ABAP Programming Error
Runtime Errors: CONVT_NO_NUMBER
ABAP Program: SAPLMEPO
Include MM06EF0B_BUCHEN
Application Component MM-PUR
An exception occurred that is explained in detail below.
This exception cannot be caught in the context of the current statement. The reason for the exception is: An attempt was made to interpret value "*" as a number. As this value contravenes the rules for displaying numbers correctly, this was not possible.
Below is the code where an exception occurred:
DATA indx.
indx = 1.
* Need to merge KNT and XEKKN
* algorithm is: if knt is old, use knt. Else use the equivalent from xekkn
LOOP AT knt.
IF knt-updkz EQ oldpos.
MOVE-CORRESPONDING knt TO lt_ekkn.
ELSE.
READ TABLE xekkn INDEX indx.
MOVE-CORRESPONDING xekkn to lt_ekkn.
indx = indx + 1.
ENDIF.
APPEND lt_ekkn.
ENDLOOP. "v 2068862
It seems that the data type of indx (char 1), but when PO item index = 9, then index = 10 (actual value is * in debug mode ), so exception is happened.
How should I solve this problem?
I also post this issue here: https://scn.sap.com/message/16146617
You are right in assuming that indx is a C(1) since you (or the author of the code) did not specify a type. Changing the line to
DATA indx TYPE i.
should solve the issue.
I am using the error function in quite a few of my functions and would like to propagate the error messages to the user. However, I obviously don't want to include information about where the error occured exactly; this information should only go to the log files.
For example, I have a class that manages the connection to a server. If the connection times out, it calls
error("Connection timed out!")
The error message is then caught by the calling code via pcall. However, the message contains not only the message I passed, but also the name of the file that caused the error and the line number:
common/net/enetclient.lua:21: Connection timed out!
The question is: Is there any way to only retrieve the error message itself, or do I have to do this manually like following:
local status, msg = pcall(someFunctionThatThrowsErrors)
if not status then
local file, msg = msg:match("(.-:%d+): (.+)")
print("Error: " .. msg)
end
Cheers,
From the documentation of the error function:
error (message [, level])
Terminates the last protected function called and returns message as the error message. Function error never returns.
Usually, error adds some information about the error position at the beginning of the message, if the message is a string. The level argument specifies how to get the error position. With level 1 (the default), the error position is where the error function was called. Level 2 points the error to where the function that called error was called; and so on. Passing a level 0 avoids the addition of error position information to the message.
From what is stated in the second paragraph, adding a level of 0 to the error call will result in the desired output:
error("Connection timed out!", 0)
Does Clarion 8 offer anything for exception handling? I know as of Clarion 5 there was no support for things like try / catch but that was released almost 10 years ago. I can't seem to find any info on how to recover from exceptions in C6 to C8 unless I was using Clarion# (aka Clarion.NET) which I'm not. If there's definitely nothing like try / catch, are there any tricks or hacks that can be used to not have a program crash when an exception is thrown even if it goes unhandled?
If it helps, I'm using version 8.0.0.8778.
EDIT 1:
Here is some sample code for a basic program that should supposedly illustrate the feature PROP:LastChanceHook, however, I can't get it to work. When I run this program, I see the first message "Start", but then nothing happens. I've tried returning 0 or 1 from Hook but that hasn't made a difference either. Every time I run this, I have to go onto the Task Manager and end the process for the program because it's not being killed.
PROGRAM
INCLUDE('CWEXCPT.INT'), ONCE
MAP
Hook(*ICWExceptionInfo), LONG
Test(LONG,LONG)
END
CODE
MESSAGE('[Sample] Start')
SYSTEM{PROP:LastChanceHook} = ADDRESS(Hook)
Test(10, 0) ! Intentionally causes an exception
MESSAGE('[Sample] After Test')
RETURN ! Tried removing this, no difference
Hook PROCEDURE(*ICWExceptionInfo info)
CODE
MESSAGE('[Sample] Start Hook')
IF info &= NULL THEN RETURN 0 END
Message('An exception!')
RETURN 1 ! 0 = don't kill, anything > 0 = tell RTL to kill the thread
Test PROCEDURE (LONG a, LONG b)
CODE
a %= b
Yes, take a look at prop:LastChanceHook in the help. It may provide enough function for your needs.
In other cases, the info at this link might also be useful:
http://clarionsharp.com/blog/tracking-down-those-pesky-gpfs/
In the next public build of C8 (it's presently Sept 27, 2012), the buttons on that exception display (shown at the link above) can be customized a bit.