Get error messages - error-handling

We are using the following code for adding new error messages while validating the document:
function addFacesMessage( message, component ){
try {
if( typeof component === 'string' ){
component = getComponent( component );
}
var clientId = null;
if( component ){
clientId = component.getClientId( facesContext );
}
facesContext.addMessage( clientId, new javax.faces.application.FacesMessage( message ) );
} catch(e){
globalScriptErrors.add(e);
requestScope.put("scriptErrors", globalScriptErrors);
}
}
We call this function in every validation routine, if an error occured:
facesContext.addMessage("",
new javax.faces.application.FacesMessage("errormessage" );
In our XPage we've got an error message box to show all errors, that have occured for the current page:
<xp:messages id="messages2" styleClass="lotusMessage lotusWarning"></xp:messages>
Now, messages are displayed in the error message box, but how can we check if there are errors for this page? We want to use this information e.g. for an popup, that only has to be displayed, if no errors are displayed in the error message box. But how do we get this information?

Use the following to check for messages:
facesContext.getMessages().hasNext()
It will return true if messages exist, and false if no messages exist.
You can use this to control the rendering of e.g. a div like this:
<xp:div rendered="#{javascript:facesContext.getMessages().hasNext()}">
</xp:div>

It should work with:
if (facesContext.getMessages().hasNext())
Here a working example:
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:if (facesContext.getMessages().hasNext())
return "there is a error message";
else
return "no message";}]]></xp:this.value>
</xp:text>
<xp:button value="no title" id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:
var message = "test";
var component = "none"
try {
if( typeof component === 'string' ){
component = getComponent( component );
}
var clientId = null;
if( component ){
clientId = component.getClientId( facesContext );
}
facesContext.addMessage( clientId, new javax.faces.application.FacesMessage( message ) );
} catch(e){
globalScriptErrors.add(e);
requestScope.put("scriptErrors", globalScriptErrors);
}
}]]></xp:this.action>
</xp:eventHandler>

Related

How to check http status code in vuejs and return value

I need to check the status code in vuejs, whether is it 200 or else. Here is my code, but i have errors.
methods:{
userSearch(){
let searchUrl = dataUrl+this.usersearch;
fetch(searchUrl).then(statusCode => {
if(statusCode == 200){
message = "Not Available"
$("#availability").innerHTML = message
}
else {
message = "Available"
$("#availability").innerHTML = message
}})
this should return in my p element with id="availability" whether the user is available or not, depending on the status code. I am calling this method in the input field on enter.
As #deceze pointed out, the fetch function resolves to a Response Object.
You can see here how to properly handle the HTTP status of the response.
But, for your code, it should be something like this:
userSearch() {
let searchUrl = dataUrl+this.usersearch;
fetch(searchUrl).then(response => {
if(response.status == 200){
message = "Not Available"
$("#availability").innerHTML = message
}
else {
message = "Available"
$("#availability").innerHTML = message
}
})
}
As just part of the code was provided, there might be other causes for the error, that I cannot see with just this snippet.

Logging from inside a Customized Bad Request Response

I'm capturing model validation errors using the code below and outputting a custom 400 response from the CustomProblemDetails object which works great. My question is, I want to log from within the CustomProblemDetails object but don't see how I can use DI. I've passed in context which gives me access to the services but is this the way to go? If so it appears I can only get access to the ILoggerFactory how do I log using ILoggerFactory?
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
var problemDetails = new CustomProblemDetails(context)
{
Type = "https://contoso.com/probs/modelvalidation",
Title = "One or more model validation errors occurred.",
Status = StatusCodes.Status400BadRequest,
Detail = "See the errors property for details.",
Instance = context.HttpContext.Request.Path
};
return new BadRequestObjectResult(problemDetails)
{
ContentTypes = { "application/problem+json" }
};
};
});
For logging in InvalidModelStateResponseFactory, you could try code like:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
var loggerFactory = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Logger From Invalid Model");
var problemDetails = new CustomProblemDetails(context)
{
Type = "https://contoso.com/probs/modelvalidation",
Title = "One or more model validation errors occurred.",
Status = StatusCodes.Status400BadRequest,
Detail = "See the errors property for details.",
Instance = context.HttpContext.Request.Path
};
logger.LogError(JsonConvert.SerializeObject(problemDetails));
return new BadRequestObjectResult(problemDetails)
{
ContentTypes = { "application/problem+json" }
};
};
});

Interactive button doesn't work properly when using pub/sub

I'm writing a Hangouts Chat bot in C# that uses pub/sub so I can host the bot on our side of a firewall. Everything seems to work well except interactive buttons within cards. If I create a button with a specific action method name, the bot does receive the CARD_CLICKED message with the appropriate action method name. However, it doesn't seem like the card in the Hangouts Chat app knows a response was sent because the bot ends up getting the CARD_CLICKED message three times before the Hangouts Chat app finally says "Unable to contact Bot. Try again later". I've been using the Google.Apis.HangoutsChat.v1 and Google.Cloud.PubSub.V1 packages from NuGet for the bot.
This is speculation, but it seems like the issue might be that interactive buttons don't work properly through pub/sub. Any help would be appreciated.
Here is a snippet of the code I have:
SubscriptionName subscriptionName = new SubscriptionName(PROJECT_ID, SUBSCRIPTION_ID);
SubscriberServiceApiClient client = SubscriberServiceApiClient.Create();
GoogleCredential credential = GoogleCredential.FromFile(CREDENTIALS_PATH_ENV_PROPERTY).CreateScoped(HANGOUTS_CHAT_API_SCOPE);
HangoutsChatService chatService = new HangoutsChatService(new BaseClientService.Initializer
{
ApplicationName = "My Bot",
HttpClientInitializer = credential
});
while (true)
{
PullResponse response = client.Pull(subscriptionName, false, 3, CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.FromTimeout(TimeSpan.FromSeconds(90)))));
if ((response.ReceivedMessages == null) || (response.ReceivedMessages.Count == 0))
Console.WriteLine("Pulled no messages.");
else
{
foreach (ReceivedMessage message in response.ReceivedMessages)
{
try
{
byte[] jsonBytes = message.Message.Data.ToByteArray();
JObject json = JObject.Parse(Encoding.UTF8.GetString(jsonBytes));
string messageType = (string)json["type"];
switch (messageType)
{
case "MESSAGE":
{
// Get text
string messageText = (string)json["message"]["text"];
Console.WriteLine($"[{messageType}] {messageText}");
// Send response
string spaceName = (string)json["space"]["name"];
SpacesResource.MessagesResource.CreateRequest request = chatService.Spaces.Messages.Create(new Message
{
Cards = new[]
{
new Card
{
Header = new CardHeader
{
Title = "Message Received!"
},
Sections = new[]
{
new Section
{
Widgets = new[]
{
new WidgetMarkup
{
Buttons = new[]
{
new Button
{
TextButton = new TextButton
{
Text = "Click Me!",
OnClick = new OnClick
{
Action = new FormAction
{
ActionMethodName = "ClickedAction"
}
}
}
}
}
}
}
}
}
}
},
Thread = new Thread
{
Name = (string)json["message"]["thread"]["name"]
}
}, spaceName);
Message responseMsg = request.Execute();
break;
}
case "CARD_CLICKED":
{
string actionMethodName = (string)json["action"]["actionMethodName"];
Console.WriteLine($"[{messageType}] {actionMethodName} at {((DateTime)json["message"]["createTime"]).ToString()}");
// Send response
string spaceName = (string)json["space"]["name"];
SpacesResource.MessagesResource.CreateRequest request = chatService.Spaces.Messages.Create(new Message
{
ActionResponse = new ActionResponse
{
Type = "UPDATE_MESSAGE"
},
Text = $"You clicked on '{actionMethodName}'.",
Thread = new Thread
{
Name = (string)json["message"]["thread"]["name"]
}
}, spaceName);
Message responseMsg = request.Execute();
break;
}
default:
{
Console.WriteLine($"[{messageType}]");
break;
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error parsing message: {ex}");
}
}
// Acknowledge the message so we don't see it again.
string[] ackIds = new string[response.ReceivedMessages.Count];
for (int i = 0; i < response.ReceivedMessages.Count; ++i)
ackIds[i] = response.ReceivedMessages[i].AckId;
client.Acknowledge(subscriptionName, ackIds);
}
}
Using buttons with Hangouts Chat API requires a custom answer including:
{
'thread': {
'name': thread_id
},
'actionResponse': {
'type': 'UPDATE_MESSAGE'
}
}
I'd recommend using Hangouts Chat API with a bot URL.

Google App Script custom error on .withFailureHandler

I would like to throw a custom error in a function called with google.script.run from code.gs so I could display adequate information in a side bar. So far I've tested the following code with no luck:
code.gs
function UserException(type, text) {
this.type = type;
this.text = text;
//this.stack = (new Error()).stack;
}
UserException.prototype = Object.create(Error.prototype);
UserException.prototype.constructor = UserException;
function assignRangeToTechnician(technician)
{
if(technician!=null)
{
//some code
}else
throw new UserException("Error","Technician was not selected");
}
sidebar.html
...
<script>
function btnSelectTech()
{
google.script.run
.withSuccessHandler(rangeSelected)
.withFailureHandler(techniciansMessage)
.assignRangeToTechnician(document.getElementById('selectTechnician').value);
}
function techniciansMessage(Message)
{
var outputMessage = document.getElementById('message');
//here is where I log the Message value
google.script.run.myLog("In techniciansMessage() - Message: " + Message);
if (Message == null)
outputMessage.innerHTML = "<p style='color:red;'>Error occured</p>";
else
if (Message.type == "Error")
outputMessage.innerHTML = "<p style='color:red;'>" + Message.text + "</p>";
else if (Message.type == "Message")
outputMessage.innerHTML = "<p style='color:#f3f3f3;'>" + Message.text + "</p>";
}
</script>
...
When I run the code the .withFailureHandler is called but the Message doesn't hold the proper value. When I log that message I read "Error: " as a content of a 'Message' parameter.
Could you please help?
Thank you.
You may refer with this SO thread. Try adding an error parameter to your function. Example:
google.script.run.withFailureHandler(function (error) {
showError(error, 'getMe');
}).getMe();
Additional reference which might help: https://github.com/google/google-apps-script-samples/blob/master/translate/Sidebar.js.html

how to make my android App faster using titanium App

I have noticed when i deployed App in Android device using titanium Alloy, Its working slowly and it seem like android App need time to redirect to next page after touch and click.it goes to next page within 3 or 4 seconds after i clicked on any UI elements(Button,view,label,image)
On other side, its working perfectly with IOS devices (iphone and ipad)
I don't know what should exactly a problem with android.I also reset my factory data in android and tested app again but still issues arrives
Is this android touch/click issue?
Please feedback on my issues and give me your suggestion how to fix it. Thanks in advance
Your problem is not the device, but probably is your login's API. I suggest you insert an indicator to bridge the waiting time like this:
----index.xml----
<Alloy>
<Window class="login_container" height="auto" horizontalWrap="true">
<ActivityIndicator id="activityIndicator" message="Wait please..."/>
----index.js----
function login(e) {
var uname = $.username.value.split(' ').join('');
var pwd = $.password.value.split(' ').join('');
if(uname == ""){
alert("Enter username.");
return false;
}
if(pwd == ""){
alert("Enter password.");
return false;
}
$.activityIndicator.show();
And before change controller add
$.activityIndicator.hide();
Below is my controller,view files for one page in titanium
----index.js---
function login(e) {
var uname = $.username.value.split(' ').join('');
var pwd = $.password.value.split(' ').join('');
if(uname == ""){
alert("Enter username.");
return false;
}
if(pwd == ""){
alert("Enter password.");
return false;
}
//if(results.length == 0){
if (Titanium.Network.networkType === Titanium.Network.NETWORK_NONE) {
alert('There is no internet connection.');
return false;
}
var loginReq = Titanium.Network.createHTTPClient();
var params = {
func : "'"+Ti.Utils.base64encode('check_login')+"'",
username : uname,
password : pwd
};
loginReq.onload = function()
{
var json = this.responseText;
var response = JSON.parse(json);
if(response == 'account_inactive'){
alert('Your account has been inactive. Please contact to your company');
//$.index.close();
var index = Alloy.createController('index').getView();
index.open();
return false;
}
if(response == 'invalid'){
alert('Invalid username or password');
//$.index.close();
var index = Alloy.createController('index').getView();
index.open();
return false;
}
else
{
results = {
iuser_id: response.iuser_id,
signup_ids: response.signup_ids,
staff_id : response.staff_id,
vusername: response.vusername,
vfirst_name: response.vfirst_name,
vlast_name: response.vlast_name,
vemail : response.vemail,
vpwd : response.vpwd
};
Ti.App.Properties.setObject("user_session",results);
results = null;
var flag = '';
if (!Ti.App.Properties.hasProperty('installed'))
{
Ti.App.Properties.setBool('app:isLoggedIn', true);
Ti.App.Properties.hasProperty('installed');
Ti.App.Properties.setBool('installed', true);
var th_sign = Alloy.createController('login').getView();
th_sign.open();
}
else
{
var th_sign = Alloy.createController('account').getView();
th_sign.open();
}
}
json = null;
response = null;
};
if(os_name == 'android'){
loginReq.open("GET", WEB_ROOT+"get_init.php");
}
else{
loginReq.open("POST", WEB_ROOT+"get_init.php");
}
loginReq.send(params);
}
$.index.open();
----index.xml-------
<Alloy>
<Window class="login_container" height="auto" horizontalWrap="true">
<ScrollView id="scrollView_index" showVerticalScrollIndicator="true" height="100%" width="100%" scrollType="vertical">
<View id="index_view">
<ImageView class="logo" image="/images/login/logo.png" top='25' />
<TextField id="username" class="usernameTxt" value="" border="0" top="230" />
<TextField id="password" class="passwordTxt" value="" border="0" top="275" />
<Button id="loginButton" class="login_bg" onClick="login">Login</Button>
</View>
</ScrollView>
</Window>
</Alloy>
I get understood what You said and explained by use of Activity indicator to wait for some time But that will solve problem only for Login Activity. But wherever I used UI utilities like, (Button Onclick, Label onclick, Image Onclick, View Onclick) It takes at least 4 to 5 seconds time to redirect to next page. I also used Loader between switching of two pages But still it takes time(4 to 5 seconds) to effect click event and redirect to next page