I have an ASP.NET webservice and some of the fields in the request are defined as enums. When entering a blank or invalid value, the response comes back as:
Parameter name: type ---> System.ArgumentException: Must specify valid information for parsing in the string.
at System.Enum.Parse(Type enumType, String value, Boolean ignoreCase)
at System.Web.Services.Protocols.ScalarFormatter.FromString(String value, Type type)
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.ScalarFormatter.FromString(String value, Type type)
at System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection collection)
at System.Web.Services.Protocols.HtmlFormParameterReader.Read(HttpRequest request)
at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
Is it possible to capture errors like this and return an XML based response instead?
No, there's no way to do this with ASMX web services.
Naturally, you can do this with WCF.
Of course, it would be better if your client sent valid data. You might want to find out why they aren't.
Sure, it would look something like this:
try
{
Enum.Parse(Type enumType, String value, Boolean ignoreCase)
}
catch (ArgumentException e)
{
//Serialise exception information from 'e' into XML
//(not shown here) and set it as the response
Response.Write(xmlMessage);
Response.End();
}
Related
I am in the process of implementing a LoanBroker with Mulesoft but have an error message when sending a request. I get the following error message back from Postman and Mulesoft Anypoint Studio:
ERROR 2021-06-27 15:20:51,133 [[MuleRuntime].uber.04: [loanbroker].LoanBrokerFlow_Gr7.CPU_LITE #254be3ee] [processor: LoanBrokerFlow_Gr7/processors/0; event: 7e49f560-d74a-11eb-b598-b66921dc5aa5] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
********************************************************************************
Message: "You called the function 'Value Selector' with these arguments:
1: Binary ("" as Binary {base: "64"})
2: Name ("amount")
But it expects one of these combinations:
(Array, Name)
(Array, String)
(Date, Name)
(DateTime, Name)
(LocalDateTime, Name)
(LocalTime, Name)
(Object, Name)
(Object, String)
(Period, Name)
(Time, Name)
1| payload.amount
^^^^^^^^^^^^^^
Trace:
at main (line: 1, column: 1)" evaluating expression: "payload.amount".
Element : LoanBrokerFlow_Gr7/processors/0 # loanbroker:bi_gruppe7.xml:34 (Copy_of_setAmount)
Element DSL : <set-variable value="#[payload.amount]" doc:name="Copy_of_setAmount" doc:id="cbcca557-1a69-4cf2-80b1-64333175589d" variableName="amount"></set-variable>
Error type : MULE:EXPRESSION
FlowStack : at LoanBrokerFlow_Gr7(LoanBrokerFlow_Gr7/processors/0 # loanbroker:bi_gruppe7.xml:34 (Copy_of_setAmount))
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
Can anyone help me?
Thanks
This generally happens when one tries to access inner value of a payload like json but incoming payload is NOT actually a json type.
One could check the payload mediaType and then try to access the amount in order to avoid Value Selector exception.
%dw 2.0
output application/java
---
if( !isEmpty(payload) and payload.^mediaType contains "json" )
payload.amount
else
read(payload, "application/json").amount //best effort
Would recommend creating a separate dataweave file like dwl/set-amount.dwl and referencing it.
You are probably sending some body in the HTTP request from Postman but Mule doesn't know how to read it. Maybe you did not the Content-Type header in the request to let DataWeave know it is a JSON (application/json) or XML (application/XML).
Ensure you are sending the right content type.
I ran into the same situation. I know exactly the base64 is a json. So, I tried to set the MIME Type by
<set-payload value="#[payload]" doc:name="Set Payload" mimeType="application/json"/>
It works for me.
I want to make a custom validator that should check the input Url is valid or not.
I want to use the following regex that I tested in expresso, but comes off invalid when used in typescript (the compiler fails to parse it):
(((ht|f)tp(s?))\://)?((([a-zA-Z0-9_\-]{2,}\.)+[a-zA-Z]{2,})|((?:(?:25[0-5]|2[0-4]\d|[01]\d\d|\d?\d)(?(\.?\d)\.)){4}))(:[a-zA-Z0-9]+)?(/[a-zA-Z0-9\-\._\?\,\'/\\\+&%\$#\=~]*)?
The above url checks for optional http:\\\ and also will validate an Ip address
The following url's should be valid :
192.1.1.1
http://abcd.xyz.in
https://192.1.1.126
abcd.jhjhj.lo
The following url's should be invalid:
192.1
http://hjdhfjfh
168.18.5
Kindly assist
The forward slashes / are not escaped in the regex.
What is valid or invalid in Javascript is valid or invalid in Typescript and vice-versa.
There may be another option for you, that relies on the URL class. The idea is to try converting the string into a URL object. If that fails, the string does not contain a valid URL.
public isAValidUrl(value: string): boolean {
try {
const url = new URL(value);
return isValid(url.pathname);
} catch (TypeError) {
return false;
}
}
isValid(value: URL): boolean {
// you may do further tests here, e.g. by checking url.pathname
// for certain patterns
}
Alternatively to returning a boolean you may return the created URL or null instead of a boolean or - if that exists in JavaScript or TypeScript: something like an Optional<URL>. You should adapt the method's name then, of course.
Is it possible to use the flowVariable inside wildcard or expression filter directly.
I need to stop the flow based on the flow Variable value.
Example: My flow Variable name keyValue have the value like customer/feed/h26/h56 in this 'h26/h56' should set dynamically but customer/feed is constant always. I need to set my filter only after '/feed/' if it contain any characters.
<flow name="testFlow1" doc:name="testFlow1">
<file:inbound-endpoint responseTimeout="10000" doc:name="File" path="c:/in"/>
.......( Many component)
<set-variable variableName="keyValue" value="#[customer/feed/h26/h56]" doc:name="Variable"/>
.......( Many component)
<message-filter doc:name="Message">
<wildcard-filter pattern="customer/feed/+*" caseSensitive="true"/>
</message-filter>
</flow>
Used + in pattern to check whether it contain one or more characters.
Also I used expression filter, not sure how to use flow Variable inside the filter expression. Could you please help me on this.
I don't want to use property filter.
Use expression filter instead, and since your expression is simple just use the startsWith method of String.
for example
<expression-filter expression="flowVars.keyValue.startsWith('customer/feed/')" doc:name="Expression"/>
this will allow messages
First of all, you can't use wildcard-filter on flowVars directly because it applies a wildcard pattern to the message payload. Here is the implementation excerpt from the org.mule.routing.filters.WildcardFilter class
public boolean accept(MuleMessage message) {
try {
return accept(message.getPayloadAsString());
} catch (Exception e) {
logger.warn("An exception occurred while filtering", e);
return false;
}
}
So it is clear that the WildcardFilter converts the payload to a String and applies the filter.
Also, in the case of regex-filter, it applies a regex pattern to the message payload. Here is an implementation excerpt from the org.mule.routing.filters.RegExFilter
public boolean accept(MuleMessage message) {
try {
return accept(message.getPayloadAsString());
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
Now coming to your question, you can very well use expression-filter as suggested by Tyrone Villaluna. But you may want to include the expression in start and end signs like ^customer/feed/.+$
And so
<expression-filter expression="flowVars.keyValue.matches('^customer/feed/.+$')" />
I'm a new User of POCO and could get HTTP response after HTTP::Request.
By the way, How do I create HTTP request with some parameters? For example, I want to set URI, http://xxxx/index.html?name=hoge&id=fuga&data=foo.
Of course I know it's possible if I set this uri directly. But I want to realize this like below. Does anyone know this way?
URI uri("http://xxx/index.html");
uri.setParam("name", "hoge");
uri.setParam("id", "fuga");
uri.setParam("data", "foo");
If you had looked up the documentation for Poco::URI, you'd see it's done with uri.addQueryParameter("name", "value"):
void addQueryParameter(
const std::string & param,
const std::string & val = ""
);
Adds "param=val" to the query; "param" may not be empty. If val is empty, only '=' is appended to the parameter.
In addition to regular encoding, function also encodes '&' and '=', if found in param or val.
You can also set all the parameters with setQueryParameters.
Unfortunately, Poco doesn't let you set the value of an existing query parameter (or remove it). If you want to do that, you have to clear the query portion of the URI and readd all the parameters you want with their values.
How to pass parameters to datamapper in mule and access them. (In XSLT, I pass them as context parameters, receive them in param and access using $ symbol). I need to do the same thing in datamapper. Any suggestions/links/example are appreciated.
Approach1:
We are using invokeTransformer method in datamapper
output.abc= invokeTransformer("MyTransformer",input.abcdef);
This MyTransformer is a java component which has this default method overridden.
#Override
public String transformMessage(MuleMessage message, String outputEncoding)
throws TransformerException {
System.out.println("Inside transformer" +message.getProperty ("sessionVariable1",PropertyScope.SESSION));
return message.getProperty("sessionVariable1",PropertyScope.SESSION);
But, the problem is I am not calling this transformer from mule flow. But, invoking it from datamapper. Hence the argument 'message' does not get passed. So, Unable to retrive that session variable to return to datamapper. Is there a way to send this argument(MuleMessage from datamapper)?
You can use input arguments with DataMapper and then refer to them in the output:
<set-variable variableName="testvar" value="value of testvar"/>
<data-mapper:transform config-ref="new_mapping_grf"">
<data-mapper:input-arguments>
<data-mapper:input-argument key="testvar">#[flowVars['testvar']]</data-mapper:input-argument>
</data-mapper:input-arguments>
</data-mapper:transform>
and
output.myField = invokeTransformer("MyTransformer",inputArguments.testvar);
or
output.myField = inputArguments.testvar;
Adding input arguments available in the DataMapper GUI through the input side green plus icon.