How to implement global error handling in Vue - vue.js

I want to have global error handling in Vue.JS, like the error handling system in Angular 2+. I have tried so much but I could not find a good approach to implement this handling.
Imagine you have many service methods and that these methods should run one after the other (I mean inside each other) so writing then and catch method inside the prevoius service is so ugly and unclean and now I'm looking for clean way to implement such way. I hope you understand what I mean.

As #Badgy mentioned you can install a Vue error handler to catch errors Vue encounters. This can be done as follows:
Vue.config.errorHandler = function (err, vm, info) {
// handle error
// `info` is a Vue-specific error info, e.g. which lifecycle hook
// the error was found in. Only available in 2.2.0+
}
The above code can be located anywhere you like in your javascript. I locate the code just before I create my vue instance. i.e before my var app = new Vue({...}); code. Because it's a global vue error handler it will handle errors from all instances of vue as well as vue components. I find that in practice it mostly catches errors that occur in the vue render methods.
You can read more about it in the official docs here: https://v2.vuejs.org/v2/api/#errorHandler
For more general (non vue related) javascript errors you still need a global error handler like so:
window.onerror = function (msg, url, line, col, error) {
//code to handle or report error goes here
}
Again, this code can be placed anywhere javascript is allowed but typically you will want to place it to run early in your javascript stack. You can read more about this here: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror
And finally, to catch a "Promise rejection" (i.e. an exception throw from a Promise function) we need to listen for unhandledrejection events since a Promise rejection is not caught by the window.onerror mechanism (thanks to #Blauhirn for the tip). In some browsers (Chrome and Edge currently) Promise rejections can be caught with the following approach:
window.addEventListener('unhandledrejection', function(event) {
//handle error here
//event.promise contains the promise object
//event.reason contains the reason for the rejection
});
For more info see this StackOverflow question: Catch all unhandled javascript promise rejections

I hope i understood your Question Right, but this could be what you are Looking for.
errorCaptured
Type: (err: Error, vm: Component, info: string) => ?boolean
Details: Called when an error from any descendent component is
captured. The hook receives three arguments: the error, the component
instance that triggered the error, and a string containing information
on where the error was captured. The hook can return false to stop the
error from propagating further.
Here is more in-Depth Info About it.
Be careful its Vue 2.5.0+

Related

UI Error while calling app script functions through app script API

I have written functions in the app script bound to a google sheet that validates sheet data and shows a pop up in the sheet when there is an error.
Now, I am calling same functions form API calls in a Node js application to return a validation response without interacting google sheet.
API calls are successful, function gets called but unable to initialize UI.
I just don't want to write duplicate functions for same purpose but without accessing UI.
I get an error that says Script error message: Exception: Cannot call SpreadsheetApp.getUi() from this context.
How do I solve this issue by retaining the UI calling functionality of the app script functions and also getting work done through API?
You can put the call in a try catch block.
try {
SpreadsheetApp.getUi();
} catch (f) {
// do nothing here
}

Cannot read properties of undefined (reading 'find') in Vue.js Meteor

Im following the tutorial here...
https://vue-tutorial.meteor.com/simple-todos/
But I get an error even just when installing the default vue meteor app.
meteor: {
$subscribe: {
'experiments': [],
},
experiments () {
return Experiments.find({}).fetch();
},
},
gives me an error
TypeError: Cannot read properties of undefined (reading 'find')"
If I console log Experiments, its there and I get the Meteor collection object. Any idea why this might be occuring??
import Experiments from '../../api/collections/Experiments'
console.log(Experiments)
Gives me
So its obviously an available object.
Just the find({}).fetch() method on it doesnt seem to be available??
UPDATE:
THE ANSWER BELOW WORKED (kind of)
experiments() {
let experimentsData = Experiments.find({}).fetch();
if (this.$subReady.experiments) {
console.log(experimentsData);
return experimentsData;
}
},
This now returns the experiments in the console log. So they are available. However rendering them to the template doesnt.
<h2>Experiments</h2>
<div v-for="exp in experiments" :key="exp.id">
{{exp.name}}
</div>
Any idea why??
Does it have to be put into a vue data object? Computed??
I thought the meteor:{} object acted kinda like computed, but it appears not??
How do I get the data onto the screen??
The answer is actually not correct.
I am experiencing the same issue from an out of the box meteor vue app created with: meteor create vanillaVueMeteor --vue
The error occurs if you define ANY function in the meteor: section of the default export (and bizarrely the first function defined is always being called regardless of whether it is actually referenced anywhere). This is obviously a bug either in the meteor vue creator or some combination of the default versions of meteor and vue libraries.
Additionally with respect to providing data to your template: you should not call fetch, just pass the result of the find which then means you won't need to wait for the subs to be ready because reactivity will update the view when the data is available. Obviously the underlying issue is preventing this all from working correctly.
UPDATE:
It seems to be an issue with 2.7.x Downgrading to the latest 2.6 worked for me:
meteor npm remove vue
meteor npm i vue#2.6 --save
It looks like you need to just use this.$subReady in your 'experiments` function to handle the timing of how the data comes in over DDP in Meteor.
I use something like this in all my subscriptions.
When the subscription starts up, the data won't be delivered from the publication the very 1st time, so that is what causes your undefined error that you are getting.
I love the Vue + Meteor combo. You can also come join the community Slack or Forum if you have questions, there are a bunch of us to help you there.
Happy Coding!
Bob
experiments () {
let experimentsData = Experiments.find({}).fetch();
if(this.$subReady.experiments){
return experimentsData;
}
},
This should resolve your issue in the UI. The HTML data will load and run before all the data from Meteor is ready, so you just use something like this:
<h2>Experiments</h2>
<div v-if="subReady.experiments" v-for="exp in experiments" :key="exp.id">
{{exp.name}}
</div>

Confusing Swift type annotations for React Native Promises

I'm playing around with React Native and attempting to write some native code that communicates over bluetooth. I'm confused by the type annotations that I need to use in order for it to work. Could someone please explain why I have to have the "resolver" and "rejecter" bits in the following two code snippets? Is there a way to write this without those unused parts?
My implementation, MyAsyncModule.swift:
#objc(MyAsyncModule)
class MyAsyncModule: NSObject {
#objc func echoAsync(
input: NSNumber,
resolver resolve: RCTPromiseResolveBlock,
rejecter reject: RCTPromiseRejectBlock
) -> Void {
resolve(input)
}
}
From my bridge file, MyAsyncModuleBridge.m
RCT_EXTERN_METHOD(echoAsync:
(nonnull NSNumber *)input
resolver:(RCTPromiseResolveBlock *)resolve
rejecter:(RCTPromiseRejectBlock *)reject
)
I am coming from scripting land so types are foreign to me, but it seems too weird that React Native refuses to identify my the echoAsync method unless both the implementation and the bridge include the resolver and rejecter bits...
The resolver and reject calls are needed to have the framework generate a "promise". A promise can be thought of as a placeholder for a value that will be made available in the future. The resolver is called when the native code is done doing its work and is ready to pass the results back to the JavaScript land. reject is used when the native side detects an error and is used to report that error from native to JavaScript land.
To get a bit deeper, when you're JavaScript calls a native function, it doesn't pause and wait for native to finish up like a normal function call. It instead just goes on executing the next line of code (notice how React-Native prevents you from setting a return value for your exported functions meaning they are explicitly making sure you don't try and wait for a return value).
So then how does native code ever report the results back to JavaScript? There are two options
callbacks (in native these have the type RCTResponseSenderBlock) when called, cause a JavaScript function to run with the passed arguments
promises (with the types RCTPromiseResolveBlock and RCTPromiseRejectBlock) which causes you success handler to run with the passed arguments when resolver is called or causes your error handler to run when reject is called.
As for async function you MUST use promises.
For more info on JavaScript promises checkout:
http://www.html5rocks.com/en/tutorials/es6/promises/
https://facebook.github.io/react-native/docs/native-modules-ios.html#promises

WinJS app with an uncatchable crash

I have random crashes in my WinJS application when navigating between pages.
The problem is that these crashes never occurs when the app is attached to the Visual Studio debugger; so I can't find where they come from.
I use the WinJS.Application.onerror event to prevent crashes, and log what happens, but as this works well when I try with a random exception, my "uncatchable" crashes doesn't seem to fire this event (I don't have anything logged).
Do you have any idea of what could cause these crashes, or any solution to find more informations ?
Sometimes errors can't fire the WinJS.Application.onerror for several reasons (in my app, the problem was in an iframe, in a page not using winjs).
When it happens, errors can be found in the event log, under "administrative events"
Found this on this link :
http://www.davepaquette.com/archive/2012/09/15/windows-8-store-app-crash-logs.aspx
Jason gives a good solution to this problem in this video (start at time 14:48). In his example, the app was crashing if you had a callback and navigated to a different page before the callback completed. Could this be the case for your app? Any more details on what is going on when you navigate?
For others (since it seems you already know about this!):
To be able to debug easier, use the WinJS.Application.OnError event. Wire up an event handler that dumps out information about the problem before the app crashes.
WinJS.Application.onerror = function (info) {
var err = {
errorMessage: info.detail.errorMessage,
errorUrl: info.detail.errorUrl,
errorLine: info.detail.errorLine,
errorCharacter: info.detail.errorCharacter,
};
Windows.Storage.ApplicationData.current.localFolder
.createFileAsync("crash.txt", Windows.Storage.CreationCollisionOption.openIfExists)
.then(function (file) {
Windows.Storage.FileIO.appendLinesAsync(file, [JSON.stringify(err)]);
});
};
The final stop for exceptions in JavaScript is actually window.onerror; not every exception will get thrown through WinJS.Application.onerror. Try hooking window.onerror directly.

How do I catch 'Uncaught typeError: Cannot read property 'isModel' of undefined' during App load?

I'm developing ST2 on Chrome which uses localstorage. From time to time, it appears that the storage schema gets corrupted. When this happens, my app fails during load with "Uncaught typeError: Cannot read property 'isModel' of undefined". The only way to get my app running is to do localstorage.clear() in the console.
I'm assuming this is an ST2 bug, since the occurrence of the corruption seems unrelated to my code, or what I do in my app.
My main question is how do I catch the exception in such a way that either the app can recover, or the user is alerted as to what is going on? Right now, the app simply fails to load. I've tried wrapping the Ext.application() in app.js, but that is executing correctly. My launch function is not being reached.
There must be some weird thing going on with your app. Probably you have found the reason meanwhile and recognised the failing bit is somewhere in your app. Anyway if you are experiencing anything like this then probably the best bet is to catch the error event and do your error handling there. I.e.
window.addEventListener("error", function(errorEvent) {
//
// Add your error handling here
//
// if returns true, the error is suppressed and not thrown
return false;
});