You cannot catch something that doesn't throw any errors. It looks like a crutch but you can override your console.error method in the code below. But don't forget that after you will have overriden console.error that throws errors!!!
console.errorWithoutExceptions = console.error;
console.error = (...messages) => {
console.errorWithoutExceptions(...messages);
throw new Error(messages[0]);
}
// now you can use
try {
// your code
console.error('test error');
} catch(e) {
// process you error with message 'test error' here
}
// don't forget to restore previous console.error after using
console.error = console.errorWithoutExceptions;
Historically, older (pre 2013) promise libraries 'swallowed' unhandled promise rejections you have not handled yourself. This has not been the case in anything written since then.
Browsers and Node.js already automatically log uncaught promise rejections or have behaviour for handling them and will log them automatically.
Moreover - by adding the you are signalling to the method calling the function that .catch is returned:undefined
// undefined if there was an error
getStuff().then(stuff => console.log(stuff));
The question one should be asking oneself when writing async code is usually "what would the synchronous version of the code do?":
function calculate() {
try {
const stuff = generateStuff();
return process(stuff);
} catch (err) {
console.error(err);
// now it's clear that this function is 'swallowing' the error.
}
}
I don't think a consumer would expect this function to return if an error occurs.undefined
So to sum things up - it is frowned upon because it surprises developers in the application flow and browsers log uncaught promise errors anyway today.
Nothing. That's the beauty of it - if you wrote:
async function getStuff() {
const stuff = await fetchStuff();
return process(stuff);
}
// or without async/await
const getStuff = fetchStuff().then(process);
In the first place you would get better errors all around anyway :)
Old versions of Node.js might not log errors or show a deprecation warning. In those versions you can use (or proper logging instrumentation) globally:console.error
// or throw to stop on errors
process.on('unhandledRejection', e => console.error(e));
You can use almost in the same manner ie.
try
{
throw new Error("hahahaha!");
}
catch (e)
{
alert(e.message)
}
But if you want to get line number and filename where error is thrown i suppose there is no crossbrowser solution. Message and name are the only standart properties of Error object. In mozilla you have also lineNumber and fileName properties.
Does all that run in a loop of some kind? Or on a timer?
Perhaps put a try-catch around the body of the loop or the method that runs all your code, add a logging framework of your choice (log4net or nlog seem good) and then in the catch log the exception. Most logging frameworks allow you to include the exception and will include stacktrace, etc.
Putting debug logging throughout the process can also help to narrow down where it's happening.
Errors and exceptions in PowerShell are structured objects. The error message you see printed on the console is actually a formatted message with information from several elements of the error/exception object. You can (re-)construct it yourself like this:
$formatstring = "{0} : {1}`n{2}`n" +
" + CategoryInfo : {3}`n" +
" + FullyQualifiedErrorId : {4}`n"
$fields = $_.InvocationInfo.MyCommand.Name,
$_.ErrorDetails.Message,
$_.InvocationInfo.PositionMessage,
$_.CategoryInfo.ToString(),
$_.FullyQualifiedErrorId
$formatstring -f $fields
If you just want the error message displayed in your block you can simply echo the current object variable (which holds the error at that point):catch
try {
...
} catch {
$_
}
If you need colored output use with a formatted string as described above:Write-Host
try {
...
} catch {
...
Write-Host -Foreground Red -Background Black ($formatstring -f $fields)
}
With that said, usually you don't want to just display the error message as-is in an exception handler (otherwise the would be pointless). The structured error/exception objects provide you with additional information that you can use for better error control. For instance you have -ErrorAction Stop with the actual error number. $_.Exception.HResult and $_.ScriptStackTrace, so you can display stacktraces when debugging. $_.Exception.StackTrace gives you access to nested exceptions that often contain additional information about the error (top level PowerShell errors can be somewhat generic). You can unroll these nested exceptions with something like this:$_.Exception.InnerException
$e = $_.Exception
$msg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n" + $e.Message
}
$msg
In your case the information you want to extract seems to be in . It's not quite clear to me if you have an object or a JSON string there, but you should be able to get information about the types and values of the members of $_.ErrorDetails.Message by running$_.ErrorDetails
$_.ErrorDetails | Get-Member
$_.ErrorDetails | Format-List *
If is an object you should be able to obtain the message string like this:$_.ErrorDetails.Message
$_.ErrorDetails.Message.message
otherwise you need to convert the JSON string to an object first:
$_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -Expand message
Depending what kind of error you're handling, exceptions of particular types might also include more specific information about the problem at hand. In your case for instance you have a which in addition to the error message (WebException) contains the actual response from the server:$_.Exception.Message
PS C:\> $e.Exception | Get-Member
TypeName: System.Net.WebException
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj), bool _Exception.E...
GetBaseException Method System.Exception GetBaseException(), System.Excep...
GetHashCode Method int GetHashCode(), int _Exception.GetHashCode()
GetObjectData Method void GetObjectData(System.Runtime.Serialization.S...
GetType Method type GetType(), type _Exception.GetType()
ToString Method string ToString(), string _Exception.ToString()
Data Property System.Collections.IDictionary Data {get;}
HelpLink Property string HelpLink {get;set;}
HResult Property int HResult {get;}
InnerException Property System.Exception InnerException {get;}
Message Property string Message {get;}
Response Property System.Net.WebResponse Response {get;}
Source Property string Source {get;set;}
StackTrace Property string StackTrace {get;}
Status Property System.Net.WebExceptionStatus Status {get;}
TargetSite Property System.Reflection.MethodBase TargetSite {get;}which provides you with information like this:
PS C:\> $e.Exception.Response
IsMutuallyAuthenticated : False
Cookies : {}
Headers : {Keep-Alive, Connection, Content-Length, Content-T...}
SupportsHeaders : True
ContentLength : 198
ContentEncoding :
ContentType : text/html; charset=iso-8859-1
CharacterSet : iso-8859-1
Server : Apache/2.4.10
LastModified : 17.07.2016 14:39:29
StatusCode : NotFound
StatusDescription : Not Found
ProtocolVersion : 1.1
ResponseUri : http://www.example.com/
Method : POST
IsFromCache : FalseSince not all exceptions have the exact same set of properties you may want to use specific handlers for particular exceptions:
try {
...
} catch [System.ArgumentException] {
# handle argument exceptions
} catch [System.Net.WebException] {
# handle web exceptions
} catch {
# handle all other exceptions
}
If you have operations that need to be done regardless of whether an error occured or not (cleanup tasks like closing a socket or a database connection) you can put them in a block after the exception handling:finally
try {
...
} catch {
...
} finally {
# cleanup operations go here
}