Is it possible in ABAP to catch DATREF_NOT_ASSIGNED using TRY-CATCH clause?
DATREF_NOT_ASSIGNED is of category ABAP programming error, which means:
"Errors in the ABAP program, such as a division by zero or a catchable exception that was not caught."
Problem: modify below code to catch the DATREF_NOT_ASSIGNED:
data gv_i type ref to i.
gv_i->*17.
Simple handling of this error is:
data gv_i type ref to i.
if gv_i is initial.
gv_i = new #( ).
endif.
gv_i->*17.
The desired solution will use TRY-CATCH or other construct for handling exceptions/errors. Below code does not work:
data gv_i type ref to i.
try.
gv_i->* = 17.
catch CX_ROOT.
gv_i = new #( ).
endtry.
You cannot catch DATREF_NOT_ASSIGNED.
The ABAP language documentation for the Dereferencing Operator ->* confirms this:
If the data reference variable contains the null reference, the non-handleable exception DATREF_NOT_ASSIGNED is raised when the dereferencing operator is used.
Use is not bound to check for null references:
data gv_i type ref to i.
if gv_i is not bound.
gv_i = new #( ).
endif.
gv_i->*17.
You cannot handle such an exception as it is purely a programming error that simply needs to be fixed.
Even CATCH SYSTEM-EXCEPTIONS OTHERS = 8 will not help.
REPORT zzz.
START-OF-SELECTION.
DATA gv_i TYPE REF TO i.
CATCH SYSTEM-EXCEPTIONS OTHERS = 8.
gv_i->* = 17.
ENDCATCH.
IF sy-subrc <> 0.
gv_i = NEW #( ).
ENDIF.
Related
In a given json document, how to validate if a json path exists ?
I am using jayway-jsonpath and have the below code
JsonPath.read(jsonDocument, jsonPath)
The above code can potentially throw below exception
com.jayway.jsonpath.PathNotFoundException: No results for path:
$['a.b.c']
In order to mitigate it, I intend to validate if the path exists before trying to read it with JsonPath.read
For reference I went through the following 2 documentations, but couldn't really get what I want.
http://www.baeldung.com/guide-to-jayway-jsonpath
https://github.com/json-path/JsonPath
Whilst it is true that you can catch an exception, like it is mentioned in the comments there might be a more elegant way to check if a path exists without writing try catch blocks all over the code.
You can use the following configuration option with jayway-jsonpath:
com.jayway.jsonpath.Option.SUPPRESS_EXCEPTIONS
With this option active no exception is thrown. If you use the read method, it simply returns null whenever a path is not found.
Here is an example with JUnit 5 and AssertJ showing how you can use this configuration option, avoiding try / catch blocks just for checking if a json path exists:
#ParameterizedTest
#ArgumentsSource(CustomerProvider.class)
void replaceStructuredPhone(JsonPathReplacementArgument jsonPathReplacementArgument) {
DocumentContext dc = jsonPathReplacementHelper.replaceStructuredPhone(
JsonPath.parse(jsonPathReplacementArgument.getCustomerJson(),
Configuration.defaultConfiguration().addOptions(Option.SUPPRESS_EXCEPTIONS)),
"$.cps[5].contactPhoneNumber", jsonPathReplacementArgument.getUnStructuredPhoneNumberType());
UnStructuredPhoneNumberType unstructRes = dc.read("$.cps[5].contactPhoneNumber.unStructuredPhoneNumber");
assertThat(unstructRes).isNotNull();
// this path does not exist, since it should have been deleted.
Object structRes = dc.read("$.cps[5].contactPhoneNumber.structuredPhoneNumber");
assertThat(structRes).isNull();
}
You can also create a JsonPath object or ReadContext with a Configuration if you have a use case to check multiple paths.
// Suppress errors thrown by JsonPath and instead return null if a path does not exist in a JSON blob.
Configuration suppressExceptionConfiguration = Configuration
.defaultConfiguration()
.addOptions(Option.SUPPRESS_EXCEPTIONS);
ReadContext jsonData = JsonPath.using(suppressExceptionConfiguration).parse(jsonString);
for (int i = 0; i < listOfPaths.size(); i++) {
String pathData = jsonData.read(listOfPaths.get(i));
if (pathData != null) {
// do something
}
I am using lua in asterisk pbx. I encounter following problem while processing json string.
json "null" value converted to function type in lua. why?
how to handle this scenario? because i am expecting nil because no value means null in json and nil means nothing in lua.
local json = require( "json" )
local inspect = require("inspect")
local myjson_str='{"Sms":{"key":"xxxxxxxxxxxxxxxxxxxxx","to":"{caller}","senderid":null,"type":"Simple","content":"Your request has been accepted in Previous Miss call. We get back to you very soon."}}'
local myjson_table = json.decode(myjson_str)
print(type(myjson_table["Sms"]["senderid"]))
print(myjson_table)
print(inspect(myjson_table))
print(json.encode(myjson_table))
out put for above is
function
table: 0xf5e770
{
Sms = {
content = "Your request has been accepted in Previous Miss call. We get back to you very soon.",
key = "xxxxxxxxxxxxxxxxxxxxx",
senderid = <function 1>,
to = "{caller}",
type = "Simple"
}
}
{"Sms":{"type":"Simple","key":"xxxxxxxxxxxxxxxxxxxxx","senderid":null,"content":"Your request has been accepted in Previous Miss call. We get back to you very soon.","to":"{caller}"}}
It is up to specific library to decide how to represent null value.
Using nil has its own problem because its not possible find either
original JSON has key with null value or there no such key at all.
So some libraries just return some unique value. Some provide
a way to pass this value like json.deconde(str, NULL_VALUE).
So answer is just read the doc/source of library you use.
Most likely it provide something like json.null value to check
either value is null. But function is really strange choice because
they have some undetermined rules of uniqueness.
Or try another library.
First of all, #moteus is right:
It is up to specific library to decide how to represent null value
If you're using the JSON library by Jeffrey Friedl the solution is to use a placeholder instead of null and serializing the table structure to a json string using designated encode options:
-- define a placeholder
NullPlaceholder = "\0"
-- use it in an internal table
tableStructure = {}
tableStructure['someNullValue'] = NullPlaceholder
-- pass the placeholder to the encode methode
encode_options = { null = NullPlaceholder }
jsonString = JSON:encode(tableStructure, nil, encode_options)
which leads to
{"someNullValue": null}
I am trying to get a Discriminated Union type from a string in F# (4.0, VS2015). My code looks like this:
type FooOrBar =Foo | Bar
let FooOrBarFromString str =
match str with
| "Foo" -> Foo
| "Bar" -> Bar
| _ -> raise (System.ArgumentException("Invalid input"))
The problem is, if the default condition is triggered, and the exception is raised, the Argument Exception is wrapped in a System.TypeInitializationException. Ex:
[<EntryPoint>]
let main argv =
let result = FooOrBarFromString "baz"
An unhandled exception of type 'System.TypeInitializationException' occurred in Project.exe
Further complicating things, the VS2015 debugger then chokes and shows "Source Not Available". Only by inspecting the inner exception in the locals view can I see what is going on.
Is there a better way of setting this up so that errors in input data don't make debugging a massive pain?
I am fully aware that Swift doesn't have a try/catch mechanism to catch exceptions (OK, Swift 2.0 now supports them). I also understand that many API methods return a NSError that will be filled with an error object if something goes wrong. So please don't point me to this question: Error-Handling in Swift-Language
But this still doesn't explain how to react to runtime errors in your own code, like array-out-of-bounds accesses or force-unwrapping an optional value that is nil. For example:
var test: String?
test = nil
println(test!) //oops!
or
var arr = [0,1,2]
for i = 0...3 {
println(arr[i]) //oops!
}
Every programmer makes such mistakes occasionally and there should be a way to at least log them for later analysis. While debugging, Xcode can show us those, but what if this happens to an end-user or beta-tester? In pure C there is signal handling and it could be used in Objective-C as well. Is there something like this in Swift? A centralized callback entered just before the app dies?
Update:
Let me rephrase the question: in a large project, it is not feasible to manually check for the above errors on every loop and force-unwrapping. When a runtime error does happen eventually, is there a callback like Objective C's segfault handling or NSSetUncaughtExceptionHandler that will get called so that the error can be logged/e-mailed together with a stacktrace of the crash?
Edit: This answer is not updated with swift 2.0. As swift now has error handling I have not updated the below answer. Some aspect of error handling will be updated in future with swift 3.0. You can follow this answer Error-Handling in Swift-Language
Swift is made to be typeSafe language.It get error at compile time rather than waiting to cause at runtime.
In first example you are using Optional.
var test: String?
First understand meaning of optional.When you specifying optional you are saying it could be nil or have no value.Now when you unwrapping test you are saying i know this value is not nil.Please unwrap it i am sure about that.So its your responsibility to see where it nil.If you are not sure about that than you should use optional binding here.When you are unsure about value always use if condition while unwrrapping
if let notNilTest = test {
//use notNilTest
}
else{
//handle error
}
In second example it should make sense to have the runtime exception handling but you can easily get this with if condition having count.So in second example as developer you should use if condition to get count of array.
From swift guide:
If you try to use subscript syntax to retrieve or set a value for an
index that is outside of an array’s existing bounds, you will trigger
a runtime error. However, you can check that an index is valid before
using it, by comparing it to the array’s count property. Except when
count is 0 (meaning the array is empty), the largest valid index in an
array will always be count - 1, because arrays are indexed from zero.
They clearly mention about this and you should take care of these things to make your code less buggy.Some things they have provided and we should know about how to use these things.
Consider using a guard statement instead of multiple if lets.
var arr = [0,1,2]
for i = 0...3 {
Guard arr[i] != nil else {
Continue
}
println(arr[i]) //oops!
}
Or instead of
if let x = some value {
If let y = someOtherVal {
If let z = yetanotherVal {
Product = x * y* z
}
}
}
Is not nearly as neat as:
Let x = someVal
Let y = someOtherVal
Let z = yetAnotherVal
Guard x != nil,
y != nil,
z != nil
Else {
Return
}
Product = x * y * z
When running the following code:
try:
key=int(input())
except ValueError as string:
print("Error is within:",string)
for example, if one puts 'rrr' this exception will rise, since 'rrr' does not support (int)
However, instead ot putting the actual string, it puts: "invalid literal for int() with base 10: 'rrr' "
How do I make it work so that the variable 'string' actually gets the wrong input that the user gave (in this example, I want it to print: 'Error is within: rrr')
Thanks a lot
Store the input and convert it to an int separately.
key_str = input()
try:
key = int(key_str)
except ValueError:
print("Error is within:", key_str)
Your issue comes from the fact that the variable string is the error message for a ValueError exception. If you wanted to print out the user's invalid input, you would need to create a variable that stores the user's input before your try/except. For example:
userInput = input()
try:
key=int(userInput)
except ValueError:
print("Error is within:",userInput)
You can just parse the error msg :D
print("Error is within:", string.args[0][41:-1])