Catch exception in LWC thrown from Apex in Salesforce - salesforce

I have the below code to throw an exception from Apex
#AuraEnabled()
public static void associateAccount(string userId, string accountSAPNumber) {
if(String.isBlank(userId) || string.isBlank(accountSAPNumber)) {
throw new AuraHandledException('Please specify both User Email2 and SAP Number2');
}
List<user> users = [SELECT Id, Name,Email FROM User WHERE Email =: userId AND IsActive = true AND Profile.Name ='OEA Customer'];
if(users == null || users.size() <= 0) {
NoDataFoundException noUsersFound = new NoDataFoundException();
noUsersFound.setMessage('No users found with the specified email address: ' + userId);
throw noUsersFound;
}
Id accountRecordTypeId = Schema.SObjectType.Account.getRecordTypeInfosByName().get('OEA Customer Location').getRecordTypeId();
accountSAPNumber = '%' + accountSAPNumber;
List<Account> accounts = [SELECT Id FROM Account WHERE RecordTypeId =:accountRecordTypeId AND SAP_Number__c like :accountSAPNumber];
if(accounts == null || accounts.size() <= 0) {
NoDataFoundException noAccountFound = new NoDataFoundException();
noAccountFound.setMessage('No accounts found with the specified SAP Number: ' + accountSAPNumber);
throw noAccountFound;
}
else if(accounts.size() > 1) {
SearchException moreThan1Account = new SearchException();
moreThan1Account.setMessage('More than 1 account found with the specified SAP Number: ' + accountSAPNumber);
throw moreThan1Account;
}
OEA_NewContactFormController.accountMethod(userId, accountSAPNumber);
}
I am not able to catch this exception in my LWC Controller using the below
continueButtonClicked() {
associateAccount({
userId: this.searchKey,
accountSAPNumber: this.accountNumber,
})
.then((result) => {
try {
console.log("return from remote call " + result);
this.modalPopUpToggleFlag = false;
} catch (error) {
console.log('some error');
}
})
.error((error) => {
console.log("some error in code");
/*if (Array.isArray(error.body)) {
console.log(
"error message :" + error.body.map((e) => e.message).join(", ")
);
} else if (typeof error.body.message === "string") {*/
//console.log("error message :" + error);
//}
})
.finally(() => {
console.log("finally message :");
});
}
This always gives me an error on the console as "Uncaught (in promise)" and with the details of the exception. How can I catch this exception in a handled way.

The correct syntax is .then().catch().finally(), while you wrote .then().error().finally().
Moreover associateAccount returns void, so there will be no result received from then. There is also no reason to wrap this.modalPopUpToggleFlag = false; in a try-catch, only if your never defined modalPopUpToggleFlag there could be an error.
continueButtonClicked() {
associateAccount({
userId: this.searchKey,
accountSAPNumber: this.accountNumber,
})
.then(() => {
console.log("return from remote call);
this.modalPopUpToggleFlag = false;
})
.catch((error) => {
console.log("some error in code:", error);
});
}
Here is a good reading about Using Promises in Javascript

Related

I was making a Discord bot...... and i keep geting this error

I was making a discord bot with a 'ban' command (discord.js) and I keep getting this error.... [parsing error unexpected token case]
the script:
case 'ban': {
if (!isMod)
return;
let userID = args.includes('<#!') ? args.replace('<#!', '').replace('>', '')
: args.includes('<#') ? args.replace('<#', '').replace('<', '') : '';
if (userID == '') {
message.reply('Invalid user ID or mention.');
return;
}
message.guild.fetchMember(userID).then(member => {
member.kick("Banned by " + message.author.tag).then(m => {
message.channel.send('🔨 Banned <#' + userID + '>.');
}).catch(() => {
console.error;
message.reply('Could not ban the specified member.');
});
};
break;
});
User.ban({reason: banReason})
You missed a bracket.
case 'ban': {
if (!isMod)
return;
let userID = args.includes('<#!') ? args.replace('<#!', '').replace('>', '')
: args.includes('<#') ? args.replace('<#', '').replace('<', '') : '';
if (userID == '') {
message.reply('Invalid user ID or mention.');
return;
}
message.guild.fetchMember(userID).then(member => {
member.kick("Banned by " + message.author.tag).then(m => {
message.channel.send('🔨 Banned <#' + userID + '>.');
}).catch(() => {
console.error;
message.reply('Could not ban the specified member.');
});
});
break;
}
Check before break statement - that was the problem.

AngularJS controller calls a MVC controller - it succeeds but kicks off an error which contains null

I have an AngularJS/MVC application that calls a MVC controller method. The method succeeds in sending an email but goes into the error function and the error variable is null.
Why is it failing?
I tried getting more on the error using a different call but the alert does not appear when using it. I guess because the return is null and can't be resolved.
Here is the AngularJS controller method.
$scope.BookMySeat = function (UserName, SeatNo) {
if (UserName) {
// The UserName is not empty. Check to see of it exists.
dataService.ValidateUsername(UserName).success(function (output) {
if (output == -1)
{
// The user name does NOT exist. Do the insert to the table.
$scope.onclick = !$scope.onclick;
console.log(UserName + SeatNo);
dataService.InsertSeat(UserName, slotNum, SeatNo).success(function (output) {
$scope.bookedSeatList = output;
var imageCollection = new Array(totalseat);
$scope.images = imageCollection;
$scope.imageUrlNotBooked = "../Images/RED.jpg";
$scope.bookcollscope = $scope.bookedSeatList;
console.log($scope.bookcollscope);
var imageCollection1 = new Array($scope.bookedSeatList);
$scope.images1 = imageCollection1;
$scope.imageUrlBooked = "../Images/GREEN.jpg";
// Alert.
alert("Seat number " + SeatNo + " has been booked for : " + UserName);
//----------------------------------------------------------------------------------------------------------
// Send an email using a MVC controller method.
// - Using $http to call to a MVC controller method.
//----------------------------------------------------------------------------------------------------------
var encodedQueryString = encodeURIComponent('emailAddress') + '=' + encodeURIComponent('dc4444#hotmail.com') + '&' + encodeURIComponent('type') + '=' + encodeURIComponent('I') + '&' + encodeURIComponent('seatNbr') + '=' + encodeURIComponent(SeatNo) + '&' + encodeURIComponent('slotNbr') + '=' + encodeURIComponent(0);
$http.get("/Home/SendAlertEmail?" + encodedQueryString).success(function (data) {
// Alert.
alert("An insert email was sent.");
}).error(function (error) {
// Error alert.
alert("Something went wrong with the insert - SendEmail. " + error);
console.log(error);
});
//$http.get("/Home/SendAlertEmail?" + encodedQueryString).success(function (data) {
// // Alert.
// alert("An insert email was sent.");
//}).error(function (xhr) {
// // Error alert.
// alert("Something went wrong with the insert - SendEmail. Status: " + xhr.status + ". Response Text: " + xhr.responseText);
// console.log(error);
//});
}).error(function (output) {
$scope.error = true;
});
}
else
{
// The user name exists.
alert("That passenger name exists. Please enter a UNIQUE passenger name in order to book a seat.");
}
console.log(output);
}).error(function (output) {
$scope.error = true;
});
}
else
{
alert("The passenger name is empty. Please enter a passenger name in order to book a seat.");
}
}
Here is the MVC controller method.
public void SendAlertEmail([FromUri] string emailAddress, [FromUri]string type, [FromUri]int seatNbr, [FromUri]int slotNbr)
{
string strHtmlMessageBody = "";
NetworkCredential NetworkCred = new NetworkCredential();
System.Net.Mail.SmtpClient smtp = new SmtpClient();
try
{
MailMessage mm = new MailMessage();
mm.From = new MailAddress("xxxxx#hotmail.com");
mm.Subject = "From the BookSeat Portal. Passenger Seat Information.";
if (type == "I")
{
strHtmlMessageBody = "<p>Your passenger seat: " + seatNbr + " has been created by the system.</p>";
}
else
{
strHtmlMessageBody = "<p>Your passenger seat number: " + seatNbr + ", slot number: " + slotNbr + " has been deleted by the system.</p>";
}
mm.Body = strHtmlMessageBody;
mm.IsBodyHtml = true;
mm.To.Add(new MailAddress(emailAddress));
smtp.Host = "smtp.live.com";
smtp.EnableSsl = true;
smtp.UseDefaultCredentials = true;
smtp.Port = 587;
NetworkCred.UserName = "xxxxx#hotmail.com";
NetworkCred.Password = "yyyyyyy";
smtp.Credentials = NetworkCred;
smtp.Send(mm);
}
catch (SmtpException smtpEx)
{
throw new Exception("SMTP exception: " + smtpEx);
}
catch (Exception ex)
{
throw new Exception("Sending email exception: " + ex);
}
}
Here is the email sent.

Node.js mssql data input layer with connection pool

This question relates to a Node.js mssql API.
I've recently updated my code to use a SQL.ConnectionPool instead of sql.connect which when combined with an async / await function allowed me to get around connection.close() errors.
In my previous (OLD) executeQuery function, I was able to pass an array which I could push values into to use with "request.input(name, value)"
Function call example:
app.get('/api/route/:id', function (req, res) {
var id = req.params.id;
let x = []
if (id != null && id != NaN) {
x.push({
Name: 'id', Value: id
})
var query = `SELECT * from [Table] where ID = #id`
executeQuery(res, query, arr);
} else {
res.send(500)
}
})
OLD Function:
var executeQuery = function (res, query, arr) {
sql.connect(dbConfig, function (err) {
if (err) {
console.log('Error while connecting to the database: ' + err)
res.send(err)
} else {
// Create the request object
var request = new sql.Request();
if (arr != null) {
if (arr.length > 0) {
for (var obj of arr) {
request.input(obj.Name, obj.Value)
}
}
}
request.query(query, function (err, rs) {
if (err) {
sql.close();
console.log('Error while querying the database : ' + err);
res.send(err);
} else {
sql.close();
console.log(rs)
res.send(rs)
}
})
}
})
}
NEW Function:
var executeQuery = async function(res, query, arr){
const pool = new sql.ConnectionPool(dbConfig);
pool.on('error', err => {
console.log('sql errors ', err);
});
try {
await pool.connect();
let result = await pool.request().query(query);
console.log('success')
res.send(result);
return {success: result};
} catch (err) {
console.log('error')
console.log(err)
res.send(err);
return {err: err};
} finally {
pool.close();
}
}
Question
How do I go about achieving the same request.input process with a ConnectionPool as I did with my previous function ( like the below )
var request = new sql.Request();
if (arr != null) {
if (arr.length > 0) {
for (var obj of arr) {
request.input(obj.Name, obj.Value)
}
}
}
Thank you.

undefined is not an object (evaluating 'storeDataFactory.createUser(user).then

the function runs and console.log shows the user object on the backend. I don't understand why it's telling me there is an issue here, and really need some guidance.
vm.register = function() {
//check that passwords match
if(vm.password != vm.passwordRepeat) {
vm.registerError = "Passwords must match.";
return;
} else {
var username = vm.username;
// console.log("Valid form. Checking for existing user",username);
storeDataFactory.userExists(username).then(function(response){
//if user exists, return error
if(response.data.length > 0) {
vm.registerError = "A user with email " + username + " already exists. Please login.";
return;
} else {
//if no user exists
if(response.data.length == 0) {
// console.log("No user exists. Continue with registration.");
}
//assign info to user object
var user = {
username: vm.username,
password: vm.password,
name: vm.name,
phone: vm.phone
};
**storeDataFactory.createUser(user).then(function(response){**
vm.user = response.data;
console.log("Created user", vm.user);
if(response.data.length > 0) {
console.log("Created user", vm.user);
vm.registerMessage = "Successful registration, please login";
vm.registerError = null;
vm.user = response.data;
}
}).catch(function(error){
console.log(error);
vm.registerError = "There was an error creating your account.";
vm.registerMessage = null;
});
}
});
}
};
The backend code:
module.exports.register = function(req, res) {
console.log('registering user', req.body);
//create the user object with hashed pass
User
.create({
username: req.body.username,
name: req.body.name,
phone: req.body.phone,
password: bcrypt.hashSync(req.body.password, bcrypt.genSaltSync(10))
}, function(err, user) {
if (err) {
console.log("Error creating account");
res
.status(400)
.json(err);
} else {
console.log("Account created!", user);
res
.status(201)
.json(user);
}
});
};
Account created! and the user object are logged on the backend. It just won't display that damn Successful Registration! Please login. message.
storeDataFactory code:
/* global angular */ angular.module('rumbleApp').factory('storeDataFactory', storeDataFactory);
function storeDataFactory($http) {
return {
userExists: userExists,
createUser: createUser
};
function userExists(username) {
return $http.get('/api/users/userExists/' + username).then(complete).catch(failed);
}
function createUser(user) {
$http.post('/api/users/register', user).then(complete).catch(failed);
}
function complete(response) {
return response;
}
function failed(error) {
console.log(error.statusText);
return "There was an error with the API call.";
}
}
Are you sure you're returning from storeDataFactory.createUser()? Can you post the code for that method?
Sounds like the code is executing, but you're not returning anything from it (hence why it thinks it's undefined)

How to catch HttpResponseException in AngularJS service?

In my WebAPI controller, I have a function that returns either a correct result or a HttpResponseException.
public async Task<SearchResult> Search([FromUri] SearchArguments args)
{
try
{
SearchResult searchResult = await _case.Search(args, true);
string validationError = searchResult.Error;
if (!string.IsNullOrEmpty(validationError))
{
throw new HttpResponseException(new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
{
ReasonPhrase = string.Format("Could not find the case. {0}", validationError)
});
}
return searchResult;
}
catch (Exception ex)
{
throw new HttpResponseException(new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError)
{
ReasonPhrase = ex.Message
});
}
}
It is used in angularjs service which calls this function using a http get request as below.
svc.Search = function (searchArgs) {
var deferred = $q.defer();
var url = 'sci/case/search?';
$http.get(sc.baseURL + url, { params: searchArgs }).
then(function (r) {
if (!r || !r.data) {
console.log('Error: No Data Returned');
deferred.reject('No Data Returned');
}
deferred.resolve(r.data);
}, function (err) {
console.log('Error: ' + err);
deferred.reject(err);
});
return deferred.promise;
}
When there is a successful result, r.data contains the expected result. But when there is HttpResponseException thrown from the controller, I can't catch the ReasonPhrase. I need to format custom error messages in the controller and display them in UI. Is HttpResponseException appropriate to accomplish this? Thank you for any suggestions.
When you throw exception the execution flow gets interrupted and internal server error will be returned as result.you should handle error and return error message as the result.
I think you better define a class to represent API call result like this :
public class ApiCallResult {
public ApiCallResult (){
Succeeded = true;
}
public object Result {get;set;}
public bool Succeeded{get;set;}
public string Message {get;set;}
}
then :
public async Task<SearchResult> Search([FromUri] SearchArguments args)
{
var result = new ApiCallResult ();
try
{
SearchResult searchResult = await _case.Search(args, true);
result.Result = searchResult;
string validationError = searchResult.Error;
if (!string.IsNullOrEmpty(validationError))
{
result.Message = string.Format("Could not find the case");
result.Succeeded = false;
}
}
catch (Exception ex)
{
result.Message = ex.Message;
result.Succeeded = false;
}
return result;
}
and inside view :
svc.Search = function (searchArgs) {
var deferred = $q.defer();
var url = 'sci/case/search?';
$http.get(sc.baseURL + url, { params: searchArgs }).
then(function (r) {
if (!r || !r.Succeeded) {
console.log('Error: No Data Returned');
deferred.reject('No Data Returned');
}
deferred.resolve(r.Result.data);
}, function (r) {
console.log('Error: ' + r.Message);
deferred.reject(r.Message);
});
return deferred.promise;
}
You should read the statusText property value in the error callback. statusText property of the response object is a string value which has the status text of the response. HttpResponseException will set the ReasonPhrase value as the status text of the response.
$http.get(sc.baseURL + url, { params: searchArgs }).
then(function (r) {
if (!r || !r.data) {
console.log('Error: No Data Returned');
deferred.reject('No Data Returned');
}
deferred.resolve(r.data);
}, function (err) {
var errMsg = err.statusText;
alert(errMsg);
});

Resources