@BackendMethod, how to throw a sane error with a message? #439
Replies: 4 comments
-
Oh actually the issue is not that the server doesn't send the correct message. It's just that when you catch the backend method call in client, the message is not there in the caught error object. |
Beta Was this translation helpful? Give feedback.
-
This may be actually because I'm using AngularJS 1.5
|
Beta Was this translation helpful? Give feedback.
-
This is how I wrap http for Remult to work with AngularJS ChangeDetection etc. Anything I need to add for proper error handling? import { GUser } from '@shared/auth';
import { Inject } from '@xxx/core';
import { Data } from '@xxx/legacy-services';
import { ExternalHttpProvider, remult } from '@shared/remult';
export class RemultHttp implements ExternalHttpProvider {
constructor(
@Inject('$http') private http: ng.IHttpService,
@Inject('$q') private q: ng.IQService,
@Inject('Data') private data: Data,
@Inject('$timeout') private timeout: ng.ITimeoutService,
@Inject('$rootScope') private root: ng.IRootScopeService
) {}
post<TData, TBody>(url: string, data: TBody): Promise<TData> {
return this.wrapPromise(
this.login().then(() =>
this.http.post(url, data).then((data) => data.data as TData)
) as Promise<TData>
);
}
delete(url: string): Promise<void> {
return this.wrapPromise(
this.login().then(() => this.http.delete(url)) as Promise<void>
);
}
put<TData, TBody>(url: string, data: TBody): Promise<TData> {
return this.wrapPromise(
this.login().then(() =>
this.http.put(url, data).then((data) => data.data)
) as Promise<TData>
);
}
get<T>(url: string): Promise<T> {
return this.wrapPromise(
this.login().then(() =>
this.http.get(url).then((data) => data.data)
) as Promise<T>
);
}
init() {
remult.apiClient.httpClient = this;
remult.apiClient.wrapMessageHandling = (handler) => {
handler();
this.triggerCd();
};
}
login(): ng.IPromise<{ token: string } | null> {
if (!this.data.User?.id) {
return this.q.resolve(null);
}
if (this.token) {
return this.q.resolve({ token: this.token });
}
const { id, email, uuid } = this.data.User;
const dto = { id, email, uuid };
return this.http
.post<{ user: GUser; token: string }>('/apix/login', dto)
.then((data) => data.data)
.then((data) => {
this.setToken(data.token);
return this.q.resolve(data);
});
}
clearToken() {
localStorage.removeItem('token');
localStorage.removeItem('tokenCreated');
}
setToken(token: string | null) {
if (token) {
localStorage.setItem('token', token);
localStorage.setItem('tokenCreated', new Date().getTime().toString());
}
}
get token(): string | null {
const token = localStorage.getItem('token');
const tokenCreated = +localStorage.getItem('tokenCreated');
return (
(tokenCreated &&
tokenCreated > new Date().getTime() - 1000 * 60 * 60 * 6 &&
token) ||
null
);
}
wrapPromise<T>(promise: Promise<T>): Promise<T> {
return promise
.then((data) => this.triggerCd(data))
.catch((err) => this.triggerCd(null, err));
}
triggerCd<T, TError>(data?: T, error?: TError): Promise<T> {
this.triggerRootCd();
this.timeout(() => {
this.triggerRootCd();
});
if (error) {
return this.q.reject(error) as Promise<never>;
} else {
return this.q.resolve(data) as Promise<T>;
}
}
private triggerRootCd() {
if (!this.root.$$phase) {
this.root.$apply();
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Ok so when AngularJS $http rejects a request, the error object is formed in a way that Remult doesn't understand - the message is in a nested property if (error) {
return this.q.reject({
status: error.status,
message: error.data?.message
}) as Promise<never>;
} else {
return this.q.resolve(data) as Promise<T>;
} |
Beta Was this translation helpful? Give feedback.
-
EDIT: I think I can solve this on my own, by returning a rejection with something that Remult can understand. Will post a solution soon.
The error comes from
remult/projects/core/src/buildRestDataProvider.ts
Line 98 in 9793be0
EDIT: Solved (last comment).
Hi,
when an error is thrown in a (static, controller, async) backend method (ie. returns a rejected promise), the client always receives error
400
Cannot set properties of undefined (setting 'httpStatusCode')
.Is there a way to throw a custom error? I'd at least need to customize the message but possibly someone would need to send back a different status code too.
Beta Was this translation helpful? Give feedback.
All reactions