How can I get Jasmine in CoffeeScript to test for exceptions? - exception

I have this code:
class root.Goal
constructor: (#name, #size) ->
if #size <= 0 then throw new Error "Goal must be larger than 0 size"
Tested by this Jasmine-CoffeeScript test:
it "cannot be of size 0", ->
expect(new p.Goal("Goal 3", 0)).toThrow "Goal must be larger than 0 size"
It appears that the exception gets thrown, but not handled by the test:
cannot be of size 0
Failures:
1) cannot be of size 0
Message:
Error: Goal must be larger than 0 size
Stacktrace:
Error: Goal must be larger than 0 size
at new Goal (/var/lib/stickshift/1d4f33cd01e442eaa154aed2e7697ca7/app-root/data/235917/prioritization/process.coffee:14:15)
Any ideas?

As you have already found you have to wrap the call to your error-throwing code in an anonymous function. If you dont the call to expect will get the "result" (if any) of your error-throwing code. So when expects gets called all the "action" is already over.

Related

Camel - Handle exception with split operator

I have simplified my use case with an Order/items example.
An order has some items.
Every item is controlled => An AvailabilityException can be thrown from "controlItem".
After the exception is thrown, item is marked as Ok and next item is handled.
onException(AvailabilityException.class)
.onExceptionOccurred(ItemProcessor)
.handled(true)
.bean(service, "markAsOk");
from(startQueue)
.split(simple("${body.items}"))
.to(direct:controlItem")
.end()
.to(successQueue);
from("direct:controlItem")
.bean(service, "controlItem");
Now I have another case :
When an unexpected exception (NullPointerException, ...) is thrown I would like to stop the process. We don't handle next items and order is redirected to an error queue.
How can I do that ?
You can use doTry and doCatch
from(startQueue)
.doTry()
.split(simple("${body.items}"))
.to(direct:controlItem")
.end()
.to(successQueue);
.doCatch(AvailabilityException.class)
....
....
.handled(true)
.doCatch(RunTimeException.class)
....
....
.handled(false)
.stop() // stop the execution
.doFinally() //optional
Instead of stop() you can write a processor there and use exchange.getContext().stop();
You can as well add another onException for RunTimeExceptions and stop the route.
Another possible way is to use the property ROUTE_STOP . You can set this property to true in a processor on exception.
exchange.setProperty(Exchange.ROUTE_STOP, Boolean.TRUE);

Should this Perl 6 CATCH block be able to change variables in the lexical scope?

I'm playing with resumable exceptions. In this example, I try to numify something that doesn't numify. I catch that and attempt to give the $value variable an appropirate value then resume execution:
try {
my $m = 'Hello';
my $value;
$value = +$m;
put "Outside value is 「{$value.^name}」";
CATCH {
when X::Str::Numeric {
put "「$m」 isn't a number!";
put "Inside value is 「{$value.^name}」";
$value = 0;
put "Inside value is now 「$value.」";
.resume;
}
default {
put "Unhandled type 「{.^name}」";
}
}
put "End of the block";
}
put "Got to the end.";
The CATCH block can see the lexical scope it is in, a resuming picks up where it left off. I expected that I'd be able to change $value and have the rest of the block use that value, but outside of the CATCH the value becomes a Failure:
「Hello」 isn't a number!
Inside value is 「Any」
Inside value is now 「0.」
Outside value is 「Failure」
End of the block
Got to the end.
What's up?
Inside of a try block, use fatal takes effect, to cause lazy exceptions returned from method or sub calls to throw immediately. Outside the lexical scope of a try block, note that:
my $value = +$m;
Would result in a Failure being assigned to $value. The try turns it into something more like:
my $value = force-failure(+$m);
Which you could imagine being defined as something like:
sub force-failure(Mu \f) { f.sink if f ~~ Failure; f }
(I'm hand-waving because the compiler spits out the code to do this inline and with a few optimizations).
In the case under consideration, the .sink triggers the exception to the thrown. The CATCH block runs. The .resume indicates that we do not wish to unwind the call stack as would normally happen with a CATCH block, so execution continues inside of force-failure, which then returns f - the Failure. This all happens prior to the assignment in the mainline code to $value; the Failure is therefore assigned, overwriting the value given by the CATCH block.
Unfortunately, you can't escape this with //= because that does the test before running the RHS (which is what we usually want it to do). However, it is possible to do:
my $numified = +$m;
my $value //= $numified;
Of course, this is all a bit of a contrived example, since the normal idiom would be to not have a try block at all, and to write it as:
my $value = +$m // 0;
Thus taking advantage of the Failure. In general, resumable exceptions need a good amount of care, because in many cases code will not be written expecting a resumption to take place. It turns out that the code generated for fatalizing a Failure is one such piece.

SSIS 2016 - ErrorColumn is 0 (zero)

I have a package with a bunch of oledb Destinations, using SSIS 2016 - which is supposed to show the exact column that generated the error.The ErrorColumn shows (0) zero, therefore I am unable to trap the column that generated the error.
Using the script below (with code that assigns "Unknown column" but it does not help, it just avoids the script fail):
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
//IDTSComponentMetaData130 componentMetaData = ComponentMetaData as IDTSComponentMetaData130;
//var component130 = this.ComponentMetaData as IDTSComponentMetaData130;
//if (component130 != null)
//{
// System.Windows.Forms.MessageBox.Show(component130.GetIdentificationStringByID(Row.ErrorColumn));
// Row.ErrorColumnName = component130.GetIdentificationStringByID(Row.ErrorColumn);
//}
IDTSComponentMetaData130 componentMetaData = ComponentMetaData as IDTSComponentMetaData130;
if (componentMetaData != null)
{
//
if (Row.wkpErrorColumn != 0)
Row.wkpErrorColumnName = componentMetaData.GetIdentificationStringByID(Row.wkpErrorColumn);
else
Row.wkpErrorColumnName = "Unknown column";
}
else
{
Row.wkpErrorColumnName = "Cannot determine";
}
Row.wkpErrorDescription = ComponentMetaData.GetErrorDescription(Row.wkpErrorCode);
}
In SSIS 2008 (and I believe also SSIS 2016), a zero error column identifies an error that affects the entire row. In the example below, I have created a package that contains only 1 data flow task in the control flow and redirecting all errors and truncations to the error output. Placed a row count task just to have somewhere to send them to.
Also placed data viewers in both error flows to see the data coming out of it.
In a package consuming data from a flat file into an OLE DB Destination:
Using these values as input data
And having name as the PK of the table
We get a PK violation, check the error description and the error column
So when the error affects the entire record, it gets an error column value of 0.
Hope this helps.
I found that
When the error is generated by the PK, the error affect the entire row, and the error column is 0
When the error is generated by a Fk, The error affect only the column, and you get the error column value different then 0

RTE 91 vs CTE Object Required: Fixing One Causes the Other?

Function printerpart(outputtext As Collection) As Collection
Dim TotalRecords As Integer 'Original build didn't include this line; no other declaration of TotalRecords, though?
Set TotalRecords = outputtext.Count
For i = 1 To TotalRecords
outputext = outputtext(i)
outputext = Replace(outputext, "&", "and")
Print #1, outputext
Next i
Set printerpart = New Collection
End Function
When attempting to run this function, an error occurs on the line assigning a value/object to TotalRecords. Initial builds did not include the Set statement on that line, but failing to include it results in RTE 91. With Set, however, the function encounters a compile-time error: Object Required.
Each call to printerpart passes outputtext as a collection of string objects.
I am aware of how terrible the variable names are and intend to fix them.
This question seems to imply that the Set statement should only be used to assign Object variables, and that lacking it is the cause of RTE 91 in most cases. Does declaring TotalRecords as an Integer make it an object? The same errors occur if TotalRecords is not declared until its assignment statement.
What is the proper method for resolving these errors in this context, given that the commonly suggested fix for one issue causes the other?
When you remove the "set" the error you get is not according to TotalRecords, it refers to outputtext, seems like what you are passing to function does not have the .count property, check again the variable passed to the function please

Using functions on callbacks of a GUI

I'm using GUIDE to create an interface where a function [x,y]=function(a,b,c,d) will be executed when the button is clicked. Im having problems to get this to work. GUIDE creates an autogenerated function with the syntax varargout = LineasA(varargin).
I'm calling the GUI using this syntax [x,y]=LineasA(a,b,c,d).
Errors I get are:
Error in ==> LineasA>LineasA_OutputFcn at 73
varargout{1} = handles.output;
??? Error using ==> feval
Output argument "varargout{2}" (and maybe others) not assigned during call to
"C:\Users\ZeTa\Documents\MATLAB\ImagenB\LineasA.m>LineasA_OutputFcn".
Error in ==> gui_mainfcn at 263
[varargout{1:nargout}] = feval(gui_State.gui_OutputFcn, gui_hFigure, [],
gui_Handles);
Error in ==> LineasA at 40
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
Error in ==> ImagenB at 17
[MatrizB,Cuenta]=LineasA(Cuenta,waveformObj,channelObj,MatrizB);
You have to be clear where you are getting the inputs to this function, and where you want the outputs to go. It is proper coding to store the inputs and outputs in the handles struct that is passed into the callback. Also, the proper callback structure is:
LineasA(hObject, eventdata, handles)
However, if you insist on calling and storing from the base workspace, you can do as follows:
LineasA(hObject, eventdata, handles)
% grab values from base workspace
Cuenta = evalin('base', 'Cuenta');
waveformObj = evalin('base', 'waveformObj');
channelObj = evalin('base', 'channelObj');
MatrizB = evalin('base', 'MatrizB');
% the rest of your code
% assign outputs
assignin('base', 'MatrizB', matrizB);
assignin('base', 'Cuenta', Cuenta);
end
However I recommend getting those values in the handles structure and not to use evalin and assignin, they are usually bad coding techniques.